2

将 lambda 表达式发布到 currentWindowsFormsSynchronizationContext时,我发现 lambda 代码在后台线程上执行:

// running on main thread here

myLabel = new Label();
this.Controls.Add(myLabel);

WindowsFormsSynchronizationContext.Current.Post( ignore => {

    // returns true !
    bool invokeRequired = myLabel.InvokeRequired; 

    // returns a background thread, not the UI thread
    int threadId = System.Threading.Thread.CurrentThread.ManagedThreadId; 

    // throws, because we are (unexpectedly) on a background, different thread
    myLabel.Text = "whatever";

},null);

此外,WindowsFormsSynchronizationContext.Current似乎返回的不是一个WindowsFormsSynchronizationContext,而是一个普通的System.Threading.SynchronizationContext

这突然发生在一个过去没有线程问题并且最近没有修改过的表单上(解决方案的其他部分是)。我尝试寻找明显的错误(例如,在后台线程上实例化表单本身的代码,或在后台线程上创建的控件),但我无法找到明显的违规行为。

也许我看错了方向?

4

1 回答 1

5

WindowsFormsSynchronizationContext.Current是一样的SynchronizationContext.Current。您应该收到一个编译器警告,提示您正在通过派生类调用基本静态成员。

检查一下SynchronizationContext.Current.GetType(),您会发现您在不同的同步上下文下运行。

在 UI 线程上捕获正确的上下文并将其存储。

于 2013-07-16T13:46:55.817 回答