如何编写C#5异步

本文关键字:异步 C#5 何编写 | 更新日期: 2023-09-27 17:57:50

我有以下场景:
当一个命令被输入时(为了测试,它是一个控制台应用程序,当它准备好时,我希望它将是一个WebService),我执行一些代码,当需要进一步的用户输入时,我立即返回命令解释器。当给出新的输入时,我希望从我离开的地方恢复处理。这听起来很像c#5异步等待模式,所以我决定试一试。我在想这个:

public void CommandParser()
{
   while(true)
   { 
      string s = Console.ReadLine();
      if (s == "do_something")
         Execute();
      else if (s == "give_parameters")
         SetParameters();
      //... 
   }
}
MySettings input;
public async void Execute()
{
  //do stuff here
  MyResult result = null
  if (/*input needed*/){
     input = new MySetting();
     result = await input.Calculate();
  }
  else { /* fill result synchronously*/}
  //do something with result here
}
public void SetParameters()
{
   if (input!=null)
      input.UseThis("something"); //now it can return from await
}

现在我的问题是,如何编写MySettings.Calculate和MySettings.UseThis?如何从第一个返回Task,以及如何从第二个返回readyness?我已经尝试了许多Task的工厂方法,但我找不到合适的方法!请帮忙!

如何编写C#5异步

一个选项是使用TaskCompletionSource<T>。这将为您构建一个任务,您可以在源代码上调用SetResultSetException,这将适当地向任务发出信号。

这就是我用来为Eduasync实现AsyncTaskMethodBuilder<T>的方法,所以您可以看看这个例子。

您需要预先设置TaskCompletionSource,或者执行一些其他协调,以便input.CalculateUseThis都知道同一个对象,但随后Calculate将只返回completionSource.Task,而UseThis将调用completionSource.SetResult

请记住,当您调用SetResult时,如果您使用控制台应用程序(或web服务),异步方法将继续在不同的线程池线程上运行,因此您无疑希望为主循环创建一个不同的TaskCompletionSource,然后用于下一轮,就像它一样。