2016-03-23 6 views
3

Предположим, у меня есть эта функция:C# породит новую задачу

void DoWork() 
{ 
    //do long work 
} 

Я хочу эту функцию, чтобы быть выполнена в другом потоке. Я привык использовать потоки, так что один из способов выполнить его на нити:

new Thread(DoWork).Start(); 

Я пытаюсь узнать новую функцию task/await C#, так что я модифицировал метод

async Task DoWork() 
{ 
    await Task.Run(delegate() { /*do stuff*/}); 
} 

Теперь я могу использовать это так:

DoWork().Wait(0); 

Или я могу изменить метод снова:

async void DoWork() 
{ 
    await Task.Run(delegate() { /*do stuff*/}); 
} 

А теперь просто позвоните:

DoWork(); 

Какое решение я должен использовать? Мне не нужен результат задания и не дожидаюсь его завершения.

+0

Я нашел это видео весьма полезным: https://www.youtube.com/watch?v=6_GTdR0gBVE –

+1

как справочник по знанию http://blog.stephencleary.com/2014/04/a-tour-of -task-part-0-overview.html – Vikas

+1

Если вам не нужен результат задания и не дожидался его завершения - в чем причина использования 'async/aw ait'? Вы можете запустить задачу и забыть об этом: 'Task.Run (() => {/ * do stuff * /})'. 'async/await' полезен, когда вам нужно выполнить некоторую работу после завершения задачи. –

ответ

4

Ответ не является ни тем, ни другим. Вы создаете тривиальную асинхронную оболочку вокруг синхронной логики.

Стивен Клири: using Task.Run for asynchronous wrappers is a code smell

Стивен Toub (Microsoft): Should I expose asynchronous wrappers for synchronous methods? (и нет, вы не должны).

Асинхронная часть вашего метода DoWork не добавляет значения. Это уменьшает ценность вашего API, делая невозможным выполнение вашего потенциально сложного «do stuff» логикой любым способом, кроме как «забыть».

Правильный подход заключается в канаву Task.Run и раздеться ваш метод вниз к самым необходимым:

void DoWork() 
{ 
    // Do long CPU-bound work, synchronously 
} 

... 

// Then, somewhere in the calling code: 
Task.Run(() => DoWork()); // Fire and forget unless you await the resulting Task or block on it. 

Task.Run в настоящее время является предпочтительным методом планирования работы на пуле потоков (как в .NET 4.6.x)

+2

+1. Кроме того, если вы действительно хотите «пожар-и-забыть» (это не «на самом деле» 90% времени, когда люди спрашивают * для «пожара и забывания»), вы можете избежать предупреждения, выполнив 'var _ = Task.Run (() => DoWork()); ' –

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