我今天嘗試使用SwitchTo方法切換到GUI線程,發現我解除它的例子不起作用,只是因爲方法不存在。爲什麼將「SwitchTo」從Async CTP/Release中刪除?
然後我發現這個Blurb的here:
我們擺脫它的原因是因爲它是如此的危險。另一種方法是捆紮內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
}
哈。現在這是一個相當古老的線程!我從來沒有成爲微軟偶爾的「這是爲了你自己的好」推理的粉絲。 – 2013-03-12 14:37:01
我已經切換到'等待Task.Run(async()=> {})' - 不是爲了避免一些空洞的危險,而僅僅是因爲我認爲它更容易閱讀。不過,我認爲你的想法是如何實現'SwitchTo()'。 – 2013-03-12 14:37:52
不知道'async()=> {}'語法,需要進一步調查,謝謝! – 2013-03-12 14:46:24