2011-05-26 2 views
3

У меня есть следующая сценария:
Когда вводится команда (для теста это консольное приложение, когда оно готово, я надеюсь, что это будет WebService) Я выполняю некоторый код, и когда требуется дальнейший ввод данных, я немедленно верните командный интерпретатор. Когда вводится новый ввод, я хочу, чтобы обработка возобновилась с того места, где я ее оставил. Это звучит так же, как и сценарий асинхронного ожидания C# 5, который я решил попробовать. Я думал об этом:Как написать асинхронный 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, но я не могу найти правильный! Пожалуйста помоги!

+0

Его не имеет прямого отношения к вашему вопросу, но как у вас есть C# 5? – soandos

+1

Я пытаюсь использовать async ctp: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=d7ccfefa-123a-40e5-8ed5-8d2edd68acf4&displaylang=en – TDaver

+0

Спасибо за ссылку. – soandos

ответ

6

Один из вариантов заключается в использовании TaskCompletionSource<T>. Это создаст для вас задачу, и вы можете вызвать SetResult или SetException на источник, который будет сигнализировать о задаче соответствующим образом.

Это то, что я использовал для implement AsyncTaskMethodBuilder<T> for Eduasync - так что вы можете посмотреть на пример.

Вы должны были бы либо настроить TaskCompletionSource заранее или выполнить какую-либо другую координацию, так что input.Calculate и UseThis оба знают о том же объекте - но тогда Calculate бы просто вернуть completionSource.Task и UseThis назвал бы completionSource.SetResult.

Имейте в виду, что при вызове SetResult метод async будет продолжать использовать другой поток потока нити, если вы используете консольное приложение (или веб-сервис), поэтому вы, без сомнения, хотите создать разныеTaskCompletionSource для основного цикла, чтобы использовать его для следующего раунда.

+0

спасибо, это выглядит очень многообещающе. Я попробую реализовать свой фактический код, а затем вернусь для принятия. – TDaver

+0

Быстрый вопрос, хотя я установил CTP, но ждать не похоже на компиляцию. Что я делаю не так? – TDaver

+0

@TDaver: Какие ошибки вы получаете? Если CTP установлен чистым образом, компилятор должен был быть соответствующим образом изменен ... –