2012-09-14 22 views
5

Для асинхронного запуска кода (например, с помощью async/await) Мне нужна правильная задача. Конечно, в структуре есть несколько предопределенных методов, которые охватывают самые частые операции, но иногда я хочу писать свои собственные. Я новичок в C#, поэтому вполне возможно, что я делаю это неправильно, но я по крайней мере не полностью доволен своей нынешней практикой. Смотрите следующий пример для того, что я делаю:Как правильно написать настраиваемый метод возврата задачи

public async Task<bool> doHeavyWork() 
    { 
     var b1 = await this.Foo(); 
     //var b2 = await Task<bool>.Factory.StartNew(Bar); //using Task.Run 
     var b2 = await Task.Run(()=>Bar()); 
     return b1 & b2; 
    } 

public Task<bool> Foo() 
    { 
     return Task.Factory.StartNew(() => 
            { 
             //do a lot of work without awaiting 
             //any other Task 
             return false; 
            }); 
    } 

public bool Bar() 
    { 
     //do a lot of work without awaiting any other task 
     return false; 
    } 

В общем, я создавать и использовать такие методы, как пример Foo, но есть «лишний» лямбда, содержащий всю логику метода, который не выглядит очень симпатичный imho. Другой вариант - использовать любой метод, например, пример Bar, однако я думаю, что это еще хуже, потому что неясно, что этот метод должен быть запущен async (помимо правильных имен методов, таких как BarAsync) и Task.Factory.StartNew может повторяться несколько раз в программе. Я не знаю, как просто сообщить компилятору, что «этот метод возвращает задачу, пожалуйста, оберните ее как целое в Задачу при вызове», что и я хочу сделать.

Наконец-то мой вопрос: как лучше всего написать такой метод? Могу ли я избавиться от «лишней» лямбды (без добавления дополнительного именованного метода, конечно)?

EDIT Как указано в Сервисе, всегда есть веская причина иметь синхронную версию метода. Асинхронная версия должна предоставляться только в том случае, если необходима абсолютная (ссылка Стивена Клири).

+0

'' без добавления дополнительного именованного метода, конечно, '' почему отвергают это как опцию? Создайте 'public bool Bar' и' public Task BarAsync'. – Servy

+0

Я хотел избежать накладных расходов. Если имеет смысл использовать метод синхронный или асинхронный, это будет нормально. Если бы не было публичного BarAsync и частного бара (чтобы скрыть это), и в этом случае я не вижу в этом большой причины. – marce

ответ

3

Если бы кто-то захотел позвонить Bar без запуска в новой теме/Задача? Что делать, если есть еще один метод, который уже находится в фоновом потоке, поэтому нет необходимости запускать новую задачу для запуска этого долго работающего кода? Что делать, если этот метод реорганизуется в библиотеку классов, которая вызывается как из контекста рабочего стола, так и из контекста ASP или консоли? В тех других контекстах этот метод, вероятно, просто нужно будет запускать напрямую, а не как Task.

Я бы сказал, что ваш код должен выглядеть как Bar, если только не является абсолютно необходимым, чтобы ни в коем случае этот код не запускался без запуска нового Task.

Также обратите внимание, что с новыми версиями .NET вы должны переключаться с Task.Factory.StartNew на Task.Run, поэтому количество кода должно уменьшаться (немного).

+1

Хорошо, получил ваше мнение. Таким образом, нет никакой силы для этого метода в функции Task, потому что это обычно плохая идея :) И спасибо за подсказку Task.Run, я как-то пропустил ее ... – marce

+3

Также см .: [Следует ли открывать асинхронные обертки для синхронных методов? ] (http://blogs.msdn.com/b/pfxteam/archive/2012/03/24/10287244.aspx) –

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