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

前端之家收集整理的这篇文章主要介绍了c# – 为什么从“Async CTP / Release”中删除“SwitchTo”?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我今天尝试使用SwitchTo方法切换到GUI线程,并发现我将其解除的示例不起作用,因为该方法不存在. @H_403_2@然后我发现这个blurb here

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

@H_403_2@我的问题是简单的:为什么是危险的?使用什么特定的危险会导致?

@H_403_2@请注意,我已经阅读了其余的帖子,所以我明白这里有技术上的限制.我的问题是,如果我知道这一点,为什么会很危险?

@H_403_2@我正在考虑重新执行帮助方法给我指定的功能,但如果有一些根本的破坏,除了有人认为这是危险的,我不会这样做.

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

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()
    {
    }
}
@H_403_2@这将允许我编写如下代码

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年有更多关于推理的信息. @H_403_2@总而言之,这不是一个好主意,有两个原因:

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

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

原文链接:https://www.f2er.com/csharp/95324.html

猜你在找的C#相关文章