iLe*_*ing 6 c# multithreading c#-4.0
这是一个简单的例子:
public event EventHandler CookinDone = delegate{};
public void CoockinRequest(){
var indicator = new ActivityIndicator();
ActivityIndicator.Show("Oooo coockin' something cool");
var bw = new BackgroundWorker();
bw.DoWork += (sender, e) => CockinService.Cook();
bw.RunWorkerCompleted += (sender, e) => {
indicator.Hide();
CookinDone.Invoke(this,null);
};
bw.RunWorkerAsync();
}
Run Code Online (Sandbox Code Playgroud)
现在,每次我使用该方法时,我都必须拦截CookinDone事件并继续前进.
var cook = new Cook();
cook.CookinDone += (sender, e) => MessageBox.Show("Yay, smells good");
cook.CoockinRequest();
Run Code Online (Sandbox Code Playgroud)
但是如何通过将方法的返回类型设置为布尔值并在Cookin完成时返回结果来简化它?
if (CoockinRequest()) MessageBox.Show('Yay, smells even better');
Run Code Online (Sandbox Code Playgroud)
如果我把while (bw.IsBusy)它放在那里它会拧我的ActivityIndicator,冻结主线程,我觉得这将是最糟糕的事情.还有一些Monitor.Wait东西和其他一些东西TaskFactory,但所有这些东西似乎太复杂,无法在简单的场景中使用.
它可能在不同的环境中也有所不同,例如某些方法对WPF应用程序有用,有些对于其他东西以及诸如此类的东西,但应该有一般模式不对吗?
你是怎么做那些家伙的?
在.NET 4中没有直接的方法可以做到这一点.这实际上非常符合下一版C#中新的async/await功能.
可以在.NET 4中使用任务并行库来实现此目的.您可以通过更改代码来返回a来执行此操作Task<bool>,以便调用者可以等待它(如果需要),或者在完成此任务时预订任务的延续.
为此,您将重写上面的代码,如下所示:
public Task<bool> CoockinRequestAsync()
{
var indicator = new ActivityIndicator();
ActivityIndicator.Show("Oooo coockin' something cool");
// This assumes Cook() returns bool...
var task = Task.Factory.StartNew(CockinService.Cook);
// Handle your removal of the indicator here....
task.ContinueWith( (t) =>
{
indicator.Hide();
}, TaskScheduler.FromCurrentSynchronizationContext());
// Return the task so the caller can schedule their own completions
return task;
}
Run Code Online (Sandbox Code Playgroud)
然后,当你去使用它时,你会写下这样的东西:
private void SomeMethod()
{
var request = this.CoockinRequestAsync();
request.ContinueWith( t =>
{
// This will run when the request completes...
bool result = t.Result;
// Use result as needed here, ie: update your UI
}, TaskScheduler.FromCurrentSynchronizationContext());
}
Run Code Online (Sandbox Code Playgroud)