2014-11-06 2 views
4

Я новичок в ASync/ждать, и я хочу, чтобы убедиться, что это способ сделать это правильно:Правильно ли это использование await/async?

public async Task DoHeavyWorkAsync() 
{ 
    await Task.Run(() => { 
     getResponseFromFarawaySlowServerAndDoSomethingWithIt(); 
    }); 
} 

public async void ConsumeAsync() 
{ 
    Task longRunningTask = DoHeavyWorkAsync(); 
    // do a lot of other stuffs here that does not depend on DoHeavyWorkAsync() 
    await longRunningTask; 
} 

Это способ использования асинхр/ждать правильно или я сделал что-то не так?

+0

зачем начинать событие, пока вам это нужно? –

+3

Этот код не компилируется, вам не хватает ключевого слова 'async' в' ConsumeAsync' –

+0

Является ли это настольным или веб-приложением? – dcastro

ответ

7

Есть несколько вещей, которые вы можете сделать:

  1. В DoHeavyWorkAsync, вы на самом деле не нужно, чтобы создать государственную машину, используя await Task.Run, вы можете просто return Task.Run:

    public Task DoHeavyWorkAsync() 
    { 
        return Task.Run(() => getResponseFromFarawaySlowServerAndDoSomethingWithIt()); 
    } 
    
  2. async void относится исключительно к async Обработчики событий. Если ваш метод асинхронного является void возвращением, он должен возвращать Task вместо:

    public async Task ConsumeAsync() 
    
  3. Если DoHeavyWorkAsync операция на основе IO, нет никакой необходимости, чтобы обернуть его внутри Task.Run, как это по сути асинхронное. Просто используя await сделаю. Более того, вы не должны делать async over sync. Вместо этого вы должны сделать вызывающему синхронного метода явно использовать Task.Run, если это необходимо на всех:

    public void DoHeavyWork() 
    { 
        getResponseFromFarawaySlowServerAndDoSomethingWithIt(); 
    } 
    

    , а затем явно завернуть его в вызывающем методе:

    Task.Run(DoHeavyWork); 
    
2

от дизайнера API точка зрения, Я бы рассмотрел метод разделенияgetResponseFromFarawaySlowServerAndDoSomethingWithIt:
getResponseFromFarawaySlowServer и doSomething().
Тогда можно обернуть только длинный метод работает с асинхронным обертке

использование бы тогда:

var response = await getResponseFromFarawaySlowServerAsync(); 
doSomething(response); 

Другое дело, что пахнет немного: getResponseFromFarawaySlowServer сама по себе не асинхронной. вызов http или вызов webservice следует ожидать внутри этого метода, если это возможно. В настоящее время вы создаете новый поток, который ничего не ждет. Это будет излишним, если вы ждали вызова HTTP вместо

поэтому вместо

string getResponseFromFarawaySlowServer(){ 
    string response = new WebClient().DownloadString(uri); 
    ... 
    return response 
} 

async Task<string> getResponseFromFarawaySlowServerAsync(){ Task.StartNew.. 

вы бы сразу:

async Task<string> getResponseFromFarawaySlowServerAsync(){ 
    string response = await new WebClient().DownloadStringAsync(uri); 
    ... 
    return response; 
} 
Смежные вопросы