2016-08-24 611 views
1

我正在開發每1小時運行一次的quartz.net作業。它執行以下方法。我正在調用for循環中的webapi。我想確保在所有線程完成後才從GetChangedScripts()方法返回?如何做到這一點或讓我做對了嗎?C#如何在for循環中調用異步等待

工作

public void Execute(IJobExecutionContext context) 
{ 
    try 
    { 
     var scripts = _scriptService.GetScripts().GetAwaiter().GetResult(); 
    } 
    catch (Exception ex) 
    { 
     _logProvider.Error("Error while executing Script Changed Notification job : " + ex); 
    } 
} 

服務方法:

public async Task<IEnumerable<ChangedScriptsByChannel>> GetScripts() 
{ 
    var result = new List<ChangedScriptsByChannel>(); 
    var currentTime = _systemClock.CurrentTime; 
    var channelsToProcess = _lastRunReader.GetChannelsToProcess().ToList(); 

    if (!channelsToProcess.Any()) return result; 

    foreach (var channel in channelsToProcess) 
    { 
      var changedScripts = await _scriptRepository.GetChangedScriptAsync(queryString); 

      if (changedScriptsList.Any()) 
      { 
       result.Add(new ChangedScriptsByChannel() 
       { 
        ChannelCode = channel.ChannelCode, 
        ChangedScripts = changedScriptsList 
       }); 
      } 
    } 

    return result; 
} 

回答

0

截至8天前有從Quartz.NET隊正式announcement指出,最新的版本,3.0 Alpha 1具有完全支持爲asyncawait。如果可能的話,我會建議升級。這將有助於你的方法,因爲你不必去做.GetAwaiter().GetResult() - 這通常是一種代碼味道。

如何在for循環中使用await

你是不是指foreach循環,如果是的話,你已經這樣做了。如果不是這樣的話,那麼改變並不是什麼驚天動地的事情。

for (int i = 0; i < channelsToProcess.Count; ++ i) 
{ 
    var changedScripts = 
     await _scriptRepository.GetChangedScriptAsync(queryString); 

    if (changedScriptsList.Any()) 
    { 
     var channel = channelsToProcess[i]; 
     result.Add(new ChangedScriptsByChannel() 
     { 
      ChannelCode = channel.ChannelCode, 
      ChangedScripts = changedScriptsList 
     }); 
    } 
} 

在任何一個forforeach環,雖然做這些以串行的方式就是這麼做的。另一種方法是使用Linq.Select來繪製所需的任務 - 然後利用Task.WhenAll