How to catch an exception thrown from an event? - silverlight

I am porting TCPClient into Silverlight and I see that the BeginConnect can throw a SocketException somehow from the asynchronous process.
In silverlight there is a Completed event for the ConnectAsync function which supplies a SocketError in it's SocketAsyncEventArgs parameter.
I am throwing a new SocketException whenever the socket fails to connect from the method my implementation of TCPClient hooked into the Completed event.
The problem lays here:
try
{
var ar = client.BeginConnect(...);
// Do stuff
client.EndConnect(ar);
}
catch(SocketException e)
{
// Handle exception here
}
The exception won't be catched here due to the fact that it is thrown from an event? Or maybe it's because the event is executed on another thread? I'm not sure. In any case the exception is not caught.

Well, this doesn't answer your question directly, but if no one has a better solution, you can create your own thread and do a Connect instead of a BeginConnect. Then, you should be able to catch the exception.

You should do a lambda to capture the errors as shown here:
http://social.msdn.microsoft.com/Forums/hu-HU/csharpgeneral/thread/0fbe2ebd-a576-4ac5-a1ed-a5d13d0cd9c8

Related

SqlServer SMO Scripting.ScriptingError event handler not firing

I have a SQL Sever 2008 R2/64-bit database server for which I'm writing some fairly basic scripting utilities with the Sql Server Management Objects (SMO). My project is a 32-bit VS2010 executable written in C#.
Most of the effort has been fairly simple and successful. The only problem I'm having is in the firing of my custom event handler that should be called in response to a Scripting Error.
The Scripter object exposes a ScriptingError event, which I have attempted to leverage thusly:
//srv contains a valid server name
Scripter scrp = new Scripter(srv);
//scrp_ScriptingError is my handler
scrp.ScriptingError += new ScriptingErrorEventHandler(scrp_ScriptingError);
My handler is declared thusly:
static void scrp_ScriptingError(object sender, ScriptingErrorEventArgs e)
{
// my handler goes here, just printing e.Current.Urn to the console
// This is merely representative, have had other things here, but
// the handler never fires
Console.WriteLine(e.Current.Value);
}
All this compiles cleanly.
My code is invoked via simple scrp.Script(urns); where urns is just an array of the database objects being scripted out. Nothing fancy:
try
{
sc = scripter.Script(urns);
}
catch (Exception e)
{
WriteLog(String.Format("Failure during scripting: {0}: Inner exception message (if any): {1}",e.Message,((e.InnerException==null)?"[None]":e.InnerException.Message)));
}
using (System.IO.StreamWriter file = new System.IO.StreamWriter(fileName,true))
{
foreach(String currentLine in sc)
{
file.WriteLine(currentLine);
file.WriteLine("GO");
}
}
The problem is that, no matter what I've tried so far, when errors occur during scripting, my ScriptingError handler never fires.
Even in debug mode within VS2010, when I set a breakpoint within the handler, and fire my scripting code, and know an error will occur, only an exception will be thrown, but the breakpoint in my ScriptingError handler never trips.
I'm in trees-for-forest mode now, not sure what I've done wrong. Am I expecting the wrong things for the ScriptingError handler?
I have searched the MSDN docs on the SMO objects and found virtually nothing on ScriptingError handlers other than the basic API calls themselves, and precious few examples on the Internet. It seems incredibly simple and straightforward to me - just assigning an event handler to the event - but there's some battery-not-included notice I've failed to note.
Pointers to my error are greatly appreciated, with a polite request for minimal brickbats if the error is exceptionally stupid on my part :)
I am not at a pc right know, but I think you should try to set the ContinueScriptingOnError option. Otherwise there would be no reason for SMO to invoke the event, but rather through an exception instead.

WCF service in WPF self host application crash when I throw a fault exception (async methods)

I have a service hosted in a WPF application with an async method with the Begin/end methods, and when I catch an exception in the service, I want to throw a faultException to warn to the client.
However, when I try to throw the faultException, the host application crash, shutdown suddenly.
In my repository, I catch the UpdateException, then, I create a custom exception, UniqueKeyException, that is throw to the caller. The caller is an auxiliar method that is called in the Begin method.
This auxiliar method, catch the UniqyeKeyException and only do a "throw", that is capture in the try/catch block of my end method. Here there is something that I don't understand, why in the end mehod this exception is catched in the block of AgregateException instead of the UniqueKeyException.
Well, anyway, in the catch block of the end method, in the AgregateException block, I check if the innerException is UniqueKeyException, if it is true, I create an object UniqueKeyArgs (a custom class with the information to send to the client), create a FaultException and finally do the throw FaultException. It is in this step, the throw, where the host application crash.
I think that I have all configure correctly, because my custom class UniqueKeyArgs is decorate as Datacontract and its properties as DataMember, in the app.config of my host application I configure the behavior to include exception details and in the contract I decorate it with faultContract.
Why the application crash?
My code is the following:
REPOSITORY
public List<Usuers> updateUsers(List<Users> paramUsers)
{
....
catch(UpdateException ex)
{
SqlException innerEx = (SqlException)ex.InnerException;
//Code 2627 is Unique Key exception from SQL Server.
if (innerEx != null && innerEx.Number == 2627)
{
//I create the conditions of searching
ConditionsUsers conditions = new conditions();
conditions.UserName = (Users)ex.StateEntries[0].Entity).userName;
//Search for the existing user
Users myUser = getUser(conditions);
string message = "the user " + conditions.userName + " exists.";
throw new UniqueKeyException(message, myUser);
}
throw;
}
SERVICE IMPLEMENTATION
//This is my auxiliar method, called in the Begin method.
private submitUpdates()
{
....
catch(UniqueKeyException ex)
{
//The code enter here
throw;
}
}
public IAsyncResult BeginUpdateUsers(List<users> paramUsers, AsyncCallback callback, object state)
{
Task<List<Users>> myTask= Task<List<Users>>.Factory.StartNew(p => sumbmitUpdates(paramUsers), state);
return myTask.ContinueWith(res => callback(myTask));
}
public List<Users> EndUpdateusers(IAsyncResult result)
{
try
{
return ((Task<List<Users>>)result).Result;
}
//Why agregateException and not is catched in the UniqueKeyException ???
catch(AgregateException ex)
{
if (innerExceptions[0] is UsuariosValorUnicoException)
{
//I assign manually the data to debug, to discard other problems.
Users myUser = new Users();
myUser.UserName = "Jhon";
myUser.Password = "pass123";
UniqueKeyArgs myArgs = new UniqueUserArgs("unique key error", myUser);
FaultException<UniqueKeyArgs> myException = new FaultException<UniqueKeyArgs>(myArgs);
//Crash here, in the throw myException
throw myException;
}
}
throw;
}
MY CONTRACT
[FaultContract(typeof(UniqueKeyArgs))]
IAsyncResult BeginUpdateUsers(List<Users> paramUser, AsyncCallback callback, object state);
List<Users> EndUpdateUsers(IAsyncResult result);
Crash when I throw myException in the End method.
I see in this post that the solution is catch the exception in the host application too, not only in the service object. However, this solution uses Application.ThreadException, that belong to System.Windows.Forms namespace, and I am using a WPF application.
How could I send the exception to the client from a service hosted in a WPF application?
Thanks.
EDIT1: well, I am use a try/catch block in the line where I throw the exception and I see that the error is that I have not indicated a reason, so when I create my FaultException I do:
FaultException<UniqueKeyArgs> myException = new FaultException<UniqueKeyArgs>(myArgs, new FaultReason("DummyReason");
In this case, the exception message is "DummyReason", the message that I set in the FaultReason, so it says me nothing. The FaultException is not throw, and throw the generic exception to the client.
In this case the host application does not shutdown, but close the connection with the client and I have to reconnect.
It seems that the problem is the creaton of the FaultException, but I don't see the problem.
#Roeal suggests that perhaps is only possible to use faultException with synch methods, but in this link I can see an example in which is used with async methods. I have seen others examples, is not the unique.
Thanks.
EDIT2: I solve my problem. My problem is that in the FaultException, T is an object that have a property that was a self tracking entity, and this is a problem, if I am not wrong, I only can use basic types as properties of the exception.
Then, in the exception, I have implmemented ISerialize. It's needed to be able to send the information to the client, without this, the client receives an exception.Detail with null properties.
Did you also declare the synchronous operation in your service contract? In that case, maybe this helps:
If fault contracts are defined on the service operation contract, the FaultContract attribute should be applied only on the synchronous operations.
-- Juval Lowy, "Programming WCF Services 3rd Edition" (p456)
I solve my problem. My problem is that in the FaultException, T is an object that have a property that was a self tracking entity, and this is a problem, if I am not wrong, I only can use basic types as properties of the exception.
Then, in the exception, I have implmemented ISerialize. It's needed to be able to send the information to the client, without this, the client receives an exception.Detail with null properties.

Dispatcher.Run vs Dispatcher.PushFrame

I have a non-ui thread that I need to pump messages on.
The normal way to do this would involve a call Dispatcher.Run() in the thread proc of my thread.
I'd like to modify this to make it more robust with regard to unhandled exceptions.
My first cut is:
for (;;)
{
var frame = new DispatcherFrame();
try
{
Dispatcher.PushFrame(frame);
break;
}
catch (Exception e)
{
frame.Continue = false;
Log("ThreadProc caught exception:\n{0}", e);
}
}
This code works and allows the dispatcher to continue pumping messages after an exception.
Does anyone know of any potential problems with this approach?
I find using a dispatcherframe can give some problems when using it with a ui thread - for example problems with focus - I think your scenario will be fine.
Have you tried catching it with:
Application.DispatcherUnhandledException
or
Dispatcher.UnhandledException
You could also try that and set Handled=true to make it continue.

Calling a webservice synchronously from a Silverlight 3 application?

I am trying to reuse some .NET code that performs some calls to a data-access-layer type service. I have managed to package up both the input to the method and the output from the method, but unfortunately the service is called from inside code that I really don't want to rewrite in order to be asynchronous.
Unfortunately, the webservice code generated in Silverlight only produces asynchronous methods, so I was wondering if anyone had working code that managed to work around this?
Note: I don't need to execute the main code path here on the UI thread, but the code in question will expect that calls it makes to the data access layers are synchronous in nature, but the entire job can be mainly executing on a background thread.
I tried the recipe found here: The Easy Way To Synchronously Call WCF Services In Silverlight, but unfortunately it times out and never completes the call.
Or rather, what seems to happen is that the completed event handler is called, but only after the method returns. I am suspecting that the event handler is called from a dispatcher or similar, and since I'm blocking the main thread here, it never completes until the code is actually back into the GUI loop.
Or something like that.
Here's my own version that I wrote before I found the above recipe, but it suffers from the same problem:
public static object ExecuteRequestOnServer(Type dalInterfaceType, string methodName, object[] arguments)
{
string securityToken = "DUMMYTOKEN";
string input = "DUMMYINPUT";
object result = null;
Exception resultException = null;
object evtLock = new object();
var evt = new System.Threading.ManualResetEvent(false);
try
{
var client = new MinGatServices.DataAccessLayerServiceSoapClient();
client.ExecuteRequestCompleted += (s, e) =>
{
resultException = e.Error;
result = e.Result;
lock (evtLock)
{
if (evt != null)
evt.Set();
}
};
client.ExecuteRequestAsync(securityToken, input);
try
{
var didComplete = evt.WaitOne(10000);
if (!didComplete)
throw new TimeoutException("A data access layer web service request timed out (" + dalInterfaceType.Name + "." + methodName + ")");
}
finally
{
client.CloseAsync();
}
}
finally
{
lock (evtLock)
{
evt.Close();
evt = null;
}
}
if (resultException != null)
throw resultException;
else
return result;
}
Basically, both recipes does this:
Set up a ManualResetEvent
Hook into the Completed event
The event handler grabs the result from the service call, and signals the event
The main thread now starts the web service call asynchronously
It then waits for the event to become signalled
However, the event handler is not called until the method above has returned, hence my code that checks for evt != null and such, to avoid TargetInvocationException from killing my program after the method has timed out.
Does anyone know:
... if it is possible at all in Silverlight 3
... what I have done wrong above?
I suspect that the MinGatServices thingy is trying to be helpful by ensuring the ExecuteRequestCompleted is dispatched on the main UI thread.
I also suspect that your code is already executing on the main UI thread which you have blocked. Never block the UI thread in Silverlight, if you need to block the UI use something like the BusyIndicator control.
The knee-jerk answer is "code asynchronously" but that doesn't satisfy your question's requirement.
One possible solution that may be less troublesome is to start the whole chunk of code from whatever user action invokes it on a different thread, using say the BackgroundWorker.
Of course the MinGatServices might be ensuring the callback occurs on the same thread that executed ExecuteRequestAsync in which case you'll need to get that to run on a different thread (jumping back to the UI thread would be acceptable):-
Deployment.Current.Dispatcher.BeginInvoke(() => client.ExecuteRequestAsync(securityToken, input));

wpf cancel backgroundworker on application exits

In my application I have a main windows and into it, in a frame I load a page. This page do a long time task when the user press a button. My problem is that when long task is being doing and the user presses the close button of the main window, the application seems to not finish because I am debugging it in VS2008 and I can see the stop button highlighted. If I want to finish I have to press stop button, the application doesn't stop the debugging automatically on application exit. I thought .NET stops automatically backgroundworkers on application exits but I am not sure after seeing this behaviour. I have tried to force and cancel background worker in unloaded event page with something like this:
private void Page_Unloaded(object sender, RoutedEventArgs e)
{
// Is the Background Worker do some work?
if (My_BgWorker != null && My_BgWorker.IsBusy)
{
//If it supports cancellation, Cancel It
if (My_BgWorker.WorkerSupportsCancellation)
{
// Tell the Background Worker to stop working.
My_BgWorker.CancelAsync();
}
}
}
but with no success. After doing CancelAsync(), a few minutes after, I can see the backgroundworker finishes and raise RunWorkerCompleted and I can see the task is completed checking e.Cancelled argument in the event but after this event is exectued the application continues without exiting and I have no idea what is doing....
I set WorkerSupportsCancellation to true to support cancel at the begining.
I would apreciate all answers. Thanks.
Cancellation is not automatic, your code in the DoWork event handler needs to handle the cancellation by checking the value of the CancellationPending property. Calling CancelAsync doesn't abort the thread, it merely sets CancellationPending to true...
For instance :
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
while(!bgw.CancellationPending)
{
...
}
}
I think Thomas Levesque pinpointed the issue.
On a general note: somewhere, some thread is still executing. You can try and find out what thread that is, by pausing the debug process (pause button, named "Break All"). At this point, the next code line executed should be highlighted. Also, you can use the Threads window (under Debug -> Windows) to see exactly which thread is still running, and where.
Perfect Thomas, setting ShutdownMode to OnMainWindowClose as you said solved my problem. Now debugger stops correctly ;) Thanks very much for helping me.
What I did is:
<Application
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
x:Class="GParts.App"
StartupUri="WinMain.xaml"
ShutdownMode="OnMainWindowClose">
<...>
</Application>
Finally I would like to do one thing respect to backgroundworker in DoWork event in case an exception is thrown by some type of error: I hanlde errors inside it with a try catch clause and into catch I do:
catch (Exception ex)
{
e.Result = ex.Message;
}
When backgroundworker finishes by an exception I want in RunWorkerCompleted to detect it with e.Error and show it. So what I do in RunWorkerCompleted is:
if (e.Cancelled)
{
// Cancelled
}
else if (e.Error != null)
{
// Exception Thrown
// Here I want to show the message that produced the exception in DoWork
// event. If I set e.Result = ex.Message in DoWork event, is e.Error here
// containing ex.Message?
}
else
{
// Completed);
}
Is e.Error in RunWorkerCompleted containing ex.Message?
Thanks.

Resources