3

我有以下场景:
当输入命令时(为了测试,它是一个控制台应用程序,当它准备好时,我希望它是一个 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 尝试了许多工厂方法,但我找不到合适的方法!请帮忙!

4

1 回答 1

6

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

这就是我用来为 Eduasync实现AsyncTaskMethodBuilder<T>的- 所以你可以看一个例子。

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

请记住,当您调用 时SetResult,如果您使用的是控制台应用程序(或 Web 服务),异步方法将继续在不同的线程池线程上运行 - 所以您无疑想为主循环创建一个不同 TaskCompletionSource的线程然后按原样用于下一轮。

于 2011-05-26T21:26:22.303 回答