2016-04-11 5 views
0

Я хочу, чтобы метод PrintOrderAsync выполнял внешний EXE для печати заказа. Код для метода PrintOrderAsync не показывает никаких ошибок синтаксисаЗадание async и ожидание

public async Task<string> PrintOrderAsync(string PrintExe, string ExePath, int nOrderNo) 
{ 
    await Task.Factory.StartNew(() => Process.Start(ExePath + PrintExe, nOrderNo.ToString())); 

     return ""; 
} 

Но я борюсь с синтаксисом для метода вызова. Вот что я пробовал:

Task<string> result = PrintOrderAsync(PrintExe, ExePath, nOrderNo); 

И я вижу синтаксическую ошибку в приведенной выше строке. Что мне не хватает?

+1

Почему вы решили использовать 'StartNew'? Вы видели это где-то в качестве примера? –

+0

@ StephenCleary Да, я видел это где-то. Но я слушаю, и если вы думаете, что код должен работать лучше с изменениями, пожалуйста, дайте мне знать. – Hidalgo

+0

@StephenCleary Теперь, когда вы задали вопрос, я пытаюсь понять, как я могу изменить/оптимизировать линию с помощью StartNew и не могу понять это. Очевидно, что вы видите что-то не так с моим синтаксисом, поэтому мне нужно узнать, как заставить его работать лучше. – Hidalgo

ответ

2

на основе кода, который вы поделились здесь вы начинаете процесс. Это касается, поскольку вы на самом деле не ожидаете результата процесса, на самом деле - это огонь и забудьте независимо от async и await ключевых слов, если вы не дождались завершения процесса. Есть несколько способов сделать это:

public static Task WaitForExitAsync(this Process process, 
    int milliseconds, 
    CancellationToken cancellationToken = default(CancellationToken)) 
{  
    return Task.Run(() => process.WaitForExit(milliseconds), cancellationToken); 
} 

Например, вот метод расширения вы можете использовать, чтобы обернуть ожидания для процесса в Task. Это может быть затем ждали, как это:

public async Task PrintOrderAsync(string PrintExe, string ExePath, int nOrderNo) 
{ 
    return Process.Start(ExePath + PrintExe, nOrderNo.ToString()) 
        .WaitForExitAsync(5000); 
} 

// Then you could await it wherever... 
await PrintOrderAsync(PrintExe, ExePath, nOrderNo); 

В качестве альтернативы, если вы не хотите ждать его завершения (то есть, вы хотите огонь и забыть, как у вас сейчас) это сделать:

Process.Start(ExePath + PrintExe, nOrderNo.ToString()) 

Не заверните его в Task или что-нибудь еще, это совершенно отдельный процесс в любом случае (лично я предпочитаю первый вариант, который я поделил).

+0

Дэвид, прежде всего спасибо за сообщение и код. Что-то меня смущает (и это я, конечно). Если я не использую async и не буду ждать (как вы указали) и просто запустите процесс с помощью Process.Start (ExePath + PrintExt, nOrderNo.ToString()), не будет ли этот процесс запущен в том же потоке, что и «основной» код и не будет ли «основной» код ждать завершения процесса? То есть, я думал, что причина использовать async и ждать - это «переместить» процесс в новый поток и, следовательно, «освободить» «основной» поток для продолжения. Ложная логика? :) – Hidalgo

+1

Совсем нет, он запускает новый процесс, полностью отключенный от вашего кода, который его начал. Попробуйте это, напишите простое консольное приложение, которое выполняет 'Process.Start (« блокнот »)'. И сразу же выйдите из консольного приложения - блокнот остается открытым и запускается в собственном процессе - на самом деле эти два процесса не могут совместно использовать потоки. –

+0

Дэвид, большое спасибо. Ты прав. Надеюсь, что все упражнения по изучению использования async и ожидания не были полной тратой времени, и я смогу использовать ее в какой-то момент. – Hidalgo

1

Попробуйте

string result = await PrintOrderAsync(PrintExe, ExePath, nOrderNo); 
+0

М. Товбин, я признаю, что почти ничего не знаю о теме, которую я здесь привел. Поэтому я не знаю, какая разница в использовании вашего синтаксиса по сравнению с ждут Task.Factory.StartNew (() => Process.Start Но спасибо за ваше предложение. – Hidalgo

+1

, когда вы выполняете задание. Factory.StartNew это закручивает новый поток и выполняет ваш Process.Start в этом потоке. Когда он закручивает новый поток, текущий поток освобождается. Это нормально, если это то, что вы пытаетесь сделать.Поскольку ваш метод PrintOrderAsync возвращает задание строки, вы должны ждать PrintOrderAsync при выполнении вызова и назначить результат строковой переменной. –

+0

М. Товбин, большое спасибо за объяснение. Но когда я меняю свой код «Задача result = PrintOrderAsync (PrintExe, ExePath, nOrderNo); с вашим кодом "string result = await PrintOrderAsync (PrintExe, ExePath, nOrderNo);" VS показывает следующую ошибку: «Оператор ожидания может использоваться только в асинхронном методе. Попробуйте сделать этот метод с модификатором« async »и изменить его тип возврата на« Задача »» – Hidalgo

Смежные вопросы