【问题标题】:BeginGetResponse from BackgroundWorker从 BackgroundWorker 开始获取响应
【发布时间】:2013-03-06 15:54:28
【问题描述】:

我正在从 UI 线程和 BackgroundWorker 线程创建一个网络请求。

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

....

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

当我从 UI 线程调用此代码时,它工作正常。当从 BackgroundWorker 线程调用时,它会在 BeginGetResponse 上冻结。

用户界面仍然是响应式的。有什么想法吗?

编辑:我发现从后台线程调用时我实际上不需要 UI 上下文。而且我认为注入一个始终有效的 ui 上下文真的很难。这是我现在可以使用的代码:

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

【问题讨论】:

    标签: c# multithreading mono webrequest


    【解决方案1】:

    您的代码依赖于 SynchronizationContext.Current 获取 UI 上下文。如果您已经在后台线程中,那么该上下文将不是 UI 的上下文。

    您可以从后台线程调用 BeginGetResponse 就好了,但您需要确保从 UI 线程调用 SynchronizationContext.Current 并以某种方式暴露给您的后台线程。

    【讨论】:

    • 我发现当从 BackgroundWorker 调用时,我的回调不需要 UI 上下文。注入 UI 上下文也非常困难。但是和以前一样的问题。即使我删除了 UI 上下文,它也会在从 BackgroundWorker 调用时冻结在 BeginGetResponse 上。请参阅我的更新答案。
    • 问题已解决。我没有正确设置 OnBgThread 变量。
    • @Sunkas 很高兴听到;根据您显示的内容,我不确定您的更改可能有什么问题。
    猜你喜欢
    • 1970-01-01
    • 2010-09-30
    • 2017-07-09
    • 2022-06-28
    • 2014-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多