gpt4 book ai didi

c# - 为什么从 Async CTP/Release 中删除 "SwitchTo"?

转载 作者:可可西里 更新时间:2023-11-01 08:10:38 26 4
gpt4 key购买 nike

我今天尝试使用 SwitchTo 方法切换到 GUI 线程,发现我从中提取它的示例不起作用,只是因为该方法不存在。

然后我找到了这个简介 here :

The reason we got rid of it was because it was so dangerous. The alternative is to bundle up your code inside TaskEx.Run...

我的问题很简单:为什么它很危险?使用它会导致哪些具体危险?

请注意,我确实阅读了该帖子的其余部分,因此我明白这里存在​​技术限制。我的问题仍然是,如果我知道这一点,为什么它危险

我正在考虑重新实现辅助方法以提供指定的功能,但如果有一些根本性的问题,除了有人认为它很危险之外,我不会这样做。

具体来说,非常天真,我会考虑如何实现所需的方法:

public static class ContextSwitcher
{
public static ThreadPoolContextSwitcher SwitchToThreadPool()
{
return new ThreadPoolContextSwitcher();
}

public static SynchronizationContextSwitcher SwitchTo(this SynchronizationContext synchronizationContext)
{
return new SynchronizationContextSwitcher(synchronizationContext);
}
}

public class SynchronizationContextSwitcher : INotifyCompletion
{
private readonly SynchronizationContext _SynchronizationContext;

public SynchronizationContextSwitcher(SynchronizationContext synchronizationContext)
{
_SynchronizationContext = synchronizationContext;
}

public SynchronizationContextSwitcher GetAwaiter()
{
return this;
}

public bool IsCompleted
{
get
{
return false;
}
}

public void OnCompleted(Action action)
{
_SynchronizationContext.Post(_ => action(), null);
}

public void GetResult()
{
}
}

public class ThreadPoolContextSwitcher : INotifyCompletion
{
public ThreadPoolContextSwitcher GetAwaiter()
{
return this;
}

public bool IsCompleted
{
get
{
return false;
}
}

public void OnCompleted(Action action)
{
ThreadPool.QueueUserWorkItem(_ => action(), null);
}

public void GetResult()
{
}
}

这将允许我编写如下代码:

public async void Test()
{
await ContextSwitcher.SwitchToThreadPool(); // ensure we're not bogging down the UI thread
// do some heavy processing
await _UIContext.SwitchTo(); // presumably saved from the main thread
// update UI with new data
}

最佳答案

Stephen Toub 在 this thread 中提供了有关推理的更多信息.

总而言之,这不是一个好主意,原因有二:

  1. 它提倡非结构化代码。如果您需要执行“繁重的处理”,则应将其放在 Task.Run 中。更好的是,将业务逻辑与 UI 逻辑分开。
  2. 错误处理和(某些)延续在未知上下文中运行。 catch/finally block 在 Test 中需要处理在线程池中运行 UI 上下文(如果它们它们在线程池上下文中运行,它们无法使用 SwitchTo 跳转到 UI 上下文)。此外,只要你 await 返回的 Task 你应该没问题(await 将在必要时更正延续上下文),但如果你有使用 ExecuteSynchronously 的显式 ContinueWith 延续,那么它们将遇到与 catch/finally block 相同的问题。

简而言之,如果没有 SwitchTo,代码会更清晰、更可预测。

关于c# - 为什么从 Async CTP/Release 中删除 "SwitchTo"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15363413/

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