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!
One option is to use
TaskCompletionSource<T>. That will build a task for you, and you can callSetResultorSetExceptionon 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
TaskCompletionSourcebeforehand or perform some other coordination so thatinput.CalculateandUseThisboth know about the same object – but thenCalculatewould just returncompletionSource.Task, andUseThiswould callcompletionSource.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 differentTaskCompletionSourcefor the main loop to then use for the next round, as it were.