加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 为什么从“Async CTP / Release”中删除“SwitchTo”?

发布时间:2020-12-15 06:32:42 所属栏目:百科 来源:网络整理
导读:我今天尝试使用SwitchTo方法切换到GUI线程,并发现我将其解除的示例不起作用,因为该方法不存在. 然后我发现这个blurb 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…
我今天尝试使用SwitchTo方法切换到GUI线程,并发现我将其解除的示例不起作用,因为该方法不存在.

然后我发现这个blurb 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年有更多关于推理的信息.

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

>它促进非结构化代码.如果你需要“重加工”,那么应该放在Task.Run中.更好的是将您的业务逻辑与UI逻辑分开.
>错误处理和(某些)连续运行在未知的上下文中.测试中的catch / finally块将需要处理线程池或UI上下文中的运行(如果它们在线程池上下文中运行,则不能使用SwitchTo跳转到UI上下文).此外,只要你等待返回的任务,你应该是OK(等待将修正继续上下文,如果需要),但是如果您有明确的ContinueWith连续使用ExecuteSynchronously,那么他们将有与catch / finally块相同的问题.

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读