如何编写C#5异步?

时间:2011-05-26 21:21:50

标签: c# asynchronous async-await c#-5.0

我有以下情况:
当输入命令时(为了测试,它是一个控制台应用程序,当它准备就绪时,我希望它将是一个WebService)我执行一些代码,当需要进一步的用户输入时,我立即返回命令解释器。当给出新输入时,我希望处理从我离开它的地方继续。这听起来很像c#5 async-await模式,我决定尝试一下。 我在想这个:

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,但我找不到合适的方法!请帮忙!

1 个答案:

答案 0 :(得分:6)

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

我曾经习惯implement AsyncTaskMethodBuilder<T> for Eduasync - 所以你可以看一下这个例子。

您需要预先设置TaskCompletionSource或执行其他协调,以便input.CalculateUseThis都知道相同的对象 - 但随后{{1只会返回CalculatecompletionSource.Task会调用UseThis

请记住,当您调用completionSource.SetResult时,如果您正在使用控制台应用程序(或Web服务),则异步方法将继续使用不同的线程池线程 - 因此您可以使用#{1}}。毫无疑问,我想为主循环创建一个不同的 SetResult,然后用于下一轮,就像它一样。