gpt4 book ai didi

wpf - 异步回调中的 SynchronizationContext.Current

转载 作者:行者123 更新时间:2023-12-04 16:13:08 28 4
gpt4 key购买 nike

对于 WinForms 和 WPF,我使用 SynchronizationContext 作为同步到 GUI 线程的方法。最近我遇到了旧式异步回调的问题:

   private void Button_Click(object sender, RoutedEventArgs e)
{
uiContext = SynchronizationContext.Current;

var cl = new TcpClient();
cl.BeginConnect("127.0.0.1", 22222, ConnectedCallback, null);
}
public void ConnectedCallback(IAsyncResult result)
{
if (SynchronizationContext.Current != uiContext)
uiContext.Post(x => MyUIOperation(), null);
else
MyUIOperation();
}

public void MyUIOperation()
{
Title = "Connected";
}

private SynchronizationContext uiContext;

这会抛出异常,因为回调函数中的 SynchronizationContext.Current 等于捕获的,因此 UI 操作是在回调的工作线程中执行的。

在 WinForms 中使用完全相同的代码可以达到我的预期。

目前,作为一种解决方法,我改为捕获当前的 ManagedThreadId 并在回调中对其进行比较。处理这个问题的正确方法是什么?

更新:

我应该补充一点,我正在修改一个非常旧的现有类,该类当前使用以下构造:

if (control.InvokeRequired())
control.BeginInvoke(SomeFunction);
else
SomeFunction();

我正在尝试删除 WinForms 依赖项,而不会对此类的客户端产生太大影响。 SomeFunction() 正在引发事件,因此如果我只调用 uiContext.Send() 或 uiContext.Post() ,执行顺序会发生变化,因为 Post() 将始终对调用进行排队,而 Send () 总是会阻塞。

另外,这只是一小段代码来显示我的问题的根源。实际上,可以从主线程调用执行 Post() 的函数。

这是针对 .NET 4.0

最佳答案

事实证明,在 .NET 4.5 中,SynchronizationContext 在回调函数中实际上是不同的,并且 if 语句的计算结果为 true。正如所讨论的那样,这是一个有意的更改here

   WPF 4.0 had a performance optimization where it would
frequently reuse the same instance of the
DispatcherSynchronizationContext when preparing the
ExecutionContext for invoking a DispatcherOperation. This
had observable impacts on behavior.
1) Some task-parallel implementations check the reference
equality of the SynchronizationContext to determine if the
completion can be inlined - a significant performance win.
2) But, the ExecutionContext would flow the
SynchronizationContext which could result in the same
instance of the DispatcherSynchronizationContext being the
current SynchronizationContext on two different threads.
The continuations would then be inlined, resulting in code
running on the wrong thread.

关于wpf - 异步回调中的 SynchronizationContext.Current,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34496387/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com