C# 推荐使用Task.whall在循环中执行任务的方法
有人能推荐我如何应用以下代码吗C# 推荐使用Task.whall在循环中执行任务的方法,c#,async-await,task,parallel.foreach,C#,Async Await,Task,Parallel.foreach,有人能推荐我如何应用以下代码吗 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.u
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循环中存在的代码组成
如果
Ut.updateFulfilment(
是线程安全的,实际上非常简单。只需将foreach的主体放入异步函数,然后将该函数传递给Select(
)即可。将Select(
的结果传递给任务。当(
在第一次执行
wait
之前,您不需要执行任何“繁重”操作,因此不需要使用Task.Run(
要获得多个线程,一旦发出Web服务请求,它将立即启动foreach
的下一个循环,而不是像以前那样等待整个方法体完成后再启动下一个循环。@Edwin:通常,有一种比使用任务更好的方法。当所有都在循环中时。y是什么“你真的想这么做吗?”斯图尔特我编辑了这个问题以表明this@StephenCleary我正在尝试以并行方式执行foreach循环体中存在的代码。如果您希望同时运行这些代码,则isUt.updateFilment(
在第一次呼叫完成之前可以多次呼叫吗?是@ScottChamberlain多次呼叫是安全的我正在获取System.Data.Datarowcollection不包含任何“选择”的定义…。此时=>sap_tickets.Rows。Select@Edwin我更新了答案,但是请确保您有System.Data.DataSetExtensions.dll
包含在项目引用中,否则找不到方法。@Edwin您也可以执行sap\u tickets.Rows.Cast()。选择(
但我喜欢sap\u tickets.AsEnumerable()。选择(
因为它比较干净。一切正常,Catch块只执行了一次,理想情况下,它应该根据我正在传递的数据执行6次。知道为什么会发生这种情况吗?Catch块将在每个条目中执行一次,可能FlagOff
或updateFulfilment
与线程sa不同就像你想象的那样,让它在应该扔的时候不扔?
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());
}
}