views:

270

answers:

2

this code causes silverlight to hang. If I remove the ManualResetEvent code, nothing happens

        private ManualResetEvent mre = new ManualResetEvent(false);

        ...

        WebClient sender = new WebClient();
        sender. += new OpenReadCompletedEventHandler(this.ReadComplete);
        sender.OpenReadAsync(new Uri(this.url+"?blob="+BODY, UriKind.Relative));

        mre.WaitOne();

    }
    public bool T = false;
    public void ReadComplete(object sender, OpenReadCompletedEventArgs e)
    {

        mre.Set();
    }
+3  A: 

You cannot block in the UI thread (cf. "mre.WaitOne"). If you absolutely need the WaitOne, you must run your code in a separate thread. This can be done as follows:

var t = new Thread(delegate()
{
    //...
    mre.WaitOne();
    //...
});

One would expect that the "mre.Set()" in the callback would be triggered. However, I've had the same problem, so apparently, the OpenReadAsync callback mechanism uses the UI thread as intermediate dispatcher. That dispatching cannot happen it is waiting for the event to be set.

Dimitri C.
Ok, I am now using threads, the ui does not hang, but still, there is no webclient connection, the ui does not update and when I debug it shows that there are no exceptions.....whats wrong?
JerA
"the ui does not update": when I saw this symptom, the problem was that exceptions were ignored in my implementation of Application.UnhandledException. Putting a Debugger.Break() call there might help.
Dimitri C.
Do you get the ReadComplete() callback?
Dimitri C.
A: 

There are only couple of reasons that I can see that might lead you believe you need this blocking wait. Either you are not aware that you should continue with your code in the complete event or you have other local state that you haven't included in your sample code that the ReadCompleted procedure doesn't have access to.

Here is some boiler plate code for handling a downloaded stream:-

string dummy = "Some value"; // local value you still need to access when download complete

WebClient wc = new WebClient();
wc.OpenReadCompleted += (s, args)
{
   if (!args.Cancelled)
   {
     try
     {
         Stream stream = args.Stream;  // This is the data you are after
         // Do stuff with stream, note the dummy variable is still accessible here.
     }
     catch (Exception err)
     {
         //Do something sensible with the exception to make sure its surfaced
     }
   }
};
sender.OpenReadAsync(new Uri(this.url+"?blob="+BODY, UriKind.Relative));
AnthonyWJones