Search code examples
multithreadingsilverlightwindows-phone-7webclientmanualresetevent

ManualResetEvent.WaitOne blocks all threads


i have following code

ThreadPool.QueueUserWorkItem(new WaitCallback(DownloadAsync), apiMethod);
downloadHandle.WaitOne();

Where DownloadAsync is

private void DownloadAsync(object _uri)
        {
            var url = _uri as string;
            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            client.DownloadStringAsync(new Uri(GLOBALS.MAIN_API_URL + url, UriKind.Absolute));
        }

void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            result = e.Result;
            downloadHandle.Set();
        }

So my problem is that downloadHandle.Set() will never called. But i don't understand why? I Create a new thread for DownloadAsync and downloadHandle.WaitOne() shouldn't block him.

That i need is create a Sync method instead of Async.

Thanks!

UPD: Updated source code with Async calling.


Solution

  • client.DownloadString is synchronous method, so your completed handler will never be called. You need to call asynchronous version: client.DownloadStringAsync()

    You can read more about DownloadStringAsync on msdn. It's also wise to put code in try-catch block and handle exceptions if you are relying on the fact, that some code should be called.

    Your code could look like this:

    private void DownloadAsync(object _uri)
    {
        try
        {
            var url = _uri as string;
            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            client.DownloadStringAsync(new Uri(GLOBALS.MAIN_API_URL + url, UriKind.Absolute));
        }
        catch //appropriate exception
        {
           //Handle exception (maybe set downloadHandle or report an error)
        }
    }
    
    void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        result = e.Result;
        downloadHandle.Set();
    }