2016-04-19 2 views
1

Может кто-нибудь порекомендовать, как я могу применить Task.WhenAll к следующему кодуРекомендуют способ использовать Task.WhenAll для выполнения задач в цикле

foreach (DataRow row in sap_tickets.Rows) 
{ 
    //#EDIT This is the beginning of the task i want to execute 
    picklist = row["absentry"].ToString(); 
    try 
    { 
     //call webservice here 
     string response = await Ut.updateFulfilment(row["order_number"].ToString()); 

    } 
    catch (Exception) 
    { 
     //log error to DB 
     Ut.FlagOff(picklist, CommonEnums.FLAG_OFF_TYPE.ERROR.ToString()); 
    } 
    //This is the end of the task i want to execute 
} 

Редактировать

Мои задачи состоит из кодов, которые существуют в пределах foreach loop , и они могут безопасно звонить несколько раз

+3

@Edwin: Как правило, есть лучший способ, чем использовать 'Task.WhenAll' в цикле. Что вы на самом деле пытаетесь сделать? –

+0

@stuartd Я отредактировал вопрос, чтобы указать это –

+0

@StephenCleary Я пытаюсь выполнить коды, которые существуют в теле цикла foreach параллельным способом. –

ответ

3

Если Ut.updateFulfilment( является потокобезопасным, на самом деле это довольно просто. Просто возьмите тело foreach и вставьте его в асинхронную функцию, затем просто передайте эту функцию в Select(. Передайте результат Select( в к Task.WhenAll(

async Task YourOriginalFunction(DataTable sap_tickets) 
{ 
    //Be user System.Data.DataSetExtensions.dll is included in the project refrences 
    //to get AsEnumerable() to work. 
    var tasks = sap_tickets.AsEnumerable().Select(BodyAsync) 
    await Task.WhenAll(tasks); 
} 

async Task BodyAsync(DataRow row) 
{ 
    picklist = row["absentry"].ToString(); 
    try 
    { 
     //call webservice here 
     string response = await Ut.updateFulfilment(row["order_number"].ToString()); 
    } 
    catch (Exception) 
    { 
     //log error to DB 
     Ut.FlagOff(picklist, CommonEnums.FLAG_OFF_TYPE.ERROR.ToString()); 
    } 
} 

Вы не делаете никакого «тяжелые», прежде чем ударить первый await так что вам не нужно использовать Task.Run(, чтобы получить несколько потоков, когда вы выдаете запрос webservice немедленно запустит следующий цикл foreach вместо того, чтобы ждать завершения всего тела метода до начала следующего цикла, как это делал ваш старый путь.

+0

я получаю System.Data.Datarowcollection не содержит определения для 'Select' .... at этот пункт => sap_tickets.Rows.Select –

+0

@Edwin Я обновил ответ, однако убедитесь, что в качестве ссылки на проект включен 'System.Data.DataSetExtensions.dll', или он не найдет метод. –

+1

@Edwin Вы также можете do 'sap_tickets.Rows.Cast () .Выберите (' но мне нравится 'sap_tickets.AsEnumerable(). Выберите (' потому что он немного чище. –