Search code examples
c#multithreadingmonowebrequest

BeginGetResponse from BackgroundWorker


I am creating a webrequest both from the UI thread and a BackgroundWorker thread.

IAsyncResult result = request.BeginGetResponse (o => {
    callCallback (o);
}, state);

....

private void callCallback (IAsyncResult o)
{
    RequestStateGen state = (RequestStateGen)o.AsyncState;
    state.context.Post (_ => {
        onGetCustomListObject (o);
    }, null);
}

When I call this code from the UI thread it works fine. When called from the BackgroundWorker thread it freezes on BeginGetResponse.

The UI is still responsive. Any thoughts?

Edit: I figured out that I actually not need the UI context when calling from my background thread. And I think it would've been really hard injecting a ui context that always is valid. Here is my code now that works:

private void callCallback (IAsyncResult o)
{
    RequestStateGen state = (RequestStateGen)o.AsyncState;
    if (!state.OnBgThread)
        {
            state.context.Post (_ => {
                onGetCustomListObject (o);
            }, null);
        }
        else
        {
            onGetCustomListObject (o);
        }
    }
}

Solution

  • Your code is reliant on SynchronizationContext.Current grabbing the UI context. If you're already in a background thread then that context will not be the UI's context.

    You can call BeginGetResponse from a background thread just fine, but you need to ensure that SynchronizationContext.Current is called from the UI thread and somehow exposed to your background thread.