Я попытался использовать метод SwitchTo сегодня, чтобы переключиться на поток GUI, и обнаружил, что пример, который я снял с него, не работает, просто потому, что метода там нет.
Затем я нашел этот рекламный блок здесь:
Причина, по которой мы избавились от этого, была потому, что это было так опасно. Альтернативой является сбор кода внутри 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
}