我有以下情况: 当输入命令时(为了测试,它是一个控制台应用程序,当它准备就绪时,我希望它将是一个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? 如何从第一个返回任务以及如何从第二个发出准备信号? 我已尝试使用许多工厂方法进行任务,但我找不到合适的方法! 请帮忙!
I have the following scenario: When a command is inputted (for test, it's a console application, when it's ready, I hope it will be a WebService) I execute some code, and when further user input is needed, I return to the command interpreter immediately. When the new input is given, I want processing to resume from where I left it. That sounds so much like c#5 async-await pattern, that I decided to give it a try. I was thinking about this:
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 }Now my question is, how to write MySettings.Calculate and MySettings.UseThis? How to return a Task from the first and how to signal readyness from the second? I've tried with many factory methods for Task, but I can't find the right one! Please help!
最满意答案
一种选择是使用TaskCompletionSource<T> 。 这将为您构建一个任务,您可以在源上调用SetResult或SetException ,这将适当地发出任务信号。
这就是我用来为Eduasync实现AsyncTaskMethodBuilder<T>的原因 - 所以你可以看一下这个例子。
您需要预先设置TaskCompletionSource或执行一些其他协调,以便input.Calculate和UseThis都知道相同的对象 - 但然后Calculate将返回completionSource.Task ,而UseThis将调用completionSource.SetResult 。
请记住,当您调用SetResult ,如果您正在使用控制台应用程序(或Web服务),则异步方法将继续使用不同的线程池线程 - 因此您无疑需要为其创建不同的 TaskCompletionSource 。主循环然后用于下一轮,因为它。
One option is to use TaskCompletionSource<T>. That will build a task for you, and you can call SetResult or SetException on the source, which will signal the task appropriately.
That's what I've used to implement AsyncTaskMethodBuilder<T> for Eduasync - so you can look at that for an example.
You'd need to either set up the TaskCompletionSource beforehand or perform some other coordination so that input.Calculate and UseThis both know about the same object - but then Calculate would just return completionSource.Task, and UseThis would call completionSource.SetResult.
Bear in mind that when you call SetResult, the async method will keep going on a different thread-pool thread if you're using a console app (or web service) - so you'd no doubt want to create a different TaskCompletionSource for the main loop to then use for the next round, as it were.
更多推荐
发布评论