C# - 在控件上调用BeginInvoke无法调用委托

时间:2015-02-05 15:56:11

标签: c# multithreading begininvoke

我遇到了一个在Windows 8.1上发生的有趣问题,而应用程序在Windows 7上正常运行。当我们在控件上调用BeginInvoke将执行切换到创建控件的UI线程以执行时,会出现问题一些UI更新。

请参阅下面的示例代码。

private void RequestReportInfoCompleted(IAsyncResult asyncResult)
{
    if (_synchronizer.InvokeRequired)
    {
        _synchronizer.BeginInvoke(new AsyncCallBack(RequestReportInfoCompleted), new object[] { asyncResult });
            return;
    }
    //some code to be executed on the UI thread
}

_synchronizer是一个用户控件,我相信,它是在调用时完全创建的。在控件上调用IsHandleCreated返回true。此外,BeginInvoke调用不会抛出异常,它会按原样进行,但从不调用委托。 我通过从创建控件的线程传递SynchronizationContext对象并通过在此对象上调用Post(使用相同的参数)替换上面的代码并且正常工作来解决问题。

private void PostRequestReportInfoCompleted(IAsyncResult asyncResult)
{
    //when returning from webservice you're in another thread. call the method below on original thread
    SynchronizationContext.Post(RequestReportInfoCompleted, asyncResult);
}

private void RequestReportInfoCompleted(object result)
{
    //some code to be executed on the UI thread
}

如果有人知道Windows 8.1中Windows的行为与Windows 7相比可能会导致此行为,那么我会感兴趣。

我们的应用程序中有许多类似的调用彼此接近(调用返回不同线程的Web服务,需要切换到UI线程进行更新),一个有趣的事实是,如果我将第一次调用切换为使用SynchronizationContext对象,所有其他调用在当前实现中正常工作。换句话说,控制在第一次成功呼叫后开始处理消息,而如果第一次呼叫失败,则所有后续呼叫都将失败。

任何想法都会有用。我感谢你的帮助。

0 个答案:

没有答案