获取错误任务参数包含空值。参数名称:Task并行库中的tasks with parallel.foreach
Getting error The tasks argument included a null value. Parameter name: tasks in Task parallel library with parallel.foreach
我正在尝试执行多个内部调用一些 http 调用的任务。
问题是当我使用 Parallel.ForEach 循环时出现错误:
The tasks argument included a null value. Parameter name: tasks
List<Task> TskList = new List<Task>();
Parallel.ForEach(dt.AsEnumerable(), row =>
//foreach (DataRow row in dt.Rows)
{
var oTsk =
new Task(
() =>
{
try
{
some http call
}
catch (Exception ex)
{
//AppendTextBox(row["ssub_msisdn"] as string + ", Error: " + ex.Message, txtBoxResponse);
}
});
TskList.Add(oTsk);
oTsk.Start();
}
);
var t = Task.WhenAll(TskList.ToArray());
try
{
await t;
}
catch { }
if (t.Status == TaskStatus.RanToCompletion)
{
SetLabel("Completed", lblProcessingStatus);
}
else if (t.Status == TaskStatus.Faulted)
{ SetLabel("Faulted", lblProcessingStatus); }
您正在尝试从不同的线程访问列表 TskList
,但没有任何同步。这可能会导致任何类型的问题。
只需这样做:
var tasks = dt.AsEnumerable().Select(row => Task.Run(() =>
{
try
{
// some http call
}
catch (Exception ex)
{
// rewrap the needed information into your custom exception object
throw YourException(ex, row["ssub_msisdn"]);
}
});
// now you are at the UI thread
foreach (var t in tasks)
{
try
{
await t;
}
catch (YourException ex)
{
AppendTextBox(ex.SsubMsisdn + ", Error: " + ex.InnerException.Message, txtBoxResponse);
}
}
Task.Run
会在线程池上启动任务,其实你不需要Parallel.ForEach
.
实际上,如果您在 try
中的代码只是进行 http 调用,则根本不需要 Task
!您可以通过使用异步版本完全避免线程,例如。 G。 HttpClient.GetByteArrayAsync
或 HttpClient.GetStreamAsync
+ Stream.CopyToAsync
.
E. g.:
HttpClient client = new HttpClient(); // maybe configure it
async Task ProcessRow(Row row) // put here the correct type
{
try
{
var str = await client.GetStringAsync(row[address]);
AppendTextBox(str, txtBoxResponse);
}
catch (HttpRequestException ex)
{
AppendTextBox(row["ssub_msisdn"] + ", Error: " + ex.Message, txtBoxResponse);
}
}
var tasks = dt.AsEnumerable().Select(row => ProcessRow(row));
await Yask.WhenAll(tasks);
我正在尝试执行多个内部调用一些 http 调用的任务。 问题是当我使用 Parallel.ForEach 循环时出现错误:
The tasks argument included a null value. Parameter name: tasks
List<Task> TskList = new List<Task>();
Parallel.ForEach(dt.AsEnumerable(), row =>
//foreach (DataRow row in dt.Rows)
{
var oTsk =
new Task(
() =>
{
try
{
some http call
}
catch (Exception ex)
{
//AppendTextBox(row["ssub_msisdn"] as string + ", Error: " + ex.Message, txtBoxResponse);
}
});
TskList.Add(oTsk);
oTsk.Start();
}
);
var t = Task.WhenAll(TskList.ToArray());
try
{
await t;
}
catch { }
if (t.Status == TaskStatus.RanToCompletion)
{
SetLabel("Completed", lblProcessingStatus);
}
else if (t.Status == TaskStatus.Faulted)
{ SetLabel("Faulted", lblProcessingStatus); }
您正在尝试从不同的线程访问列表 TskList
,但没有任何同步。这可能会导致任何类型的问题。
只需这样做:
var tasks = dt.AsEnumerable().Select(row => Task.Run(() =>
{
try
{
// some http call
}
catch (Exception ex)
{
// rewrap the needed information into your custom exception object
throw YourException(ex, row["ssub_msisdn"]);
}
});
// now you are at the UI thread
foreach (var t in tasks)
{
try
{
await t;
}
catch (YourException ex)
{
AppendTextBox(ex.SsubMsisdn + ", Error: " + ex.InnerException.Message, txtBoxResponse);
}
}
Task.Run
会在线程池上启动任务,其实你不需要Parallel.ForEach
.
实际上,如果您在 try
中的代码只是进行 http 调用,则根本不需要 Task
!您可以通过使用异步版本完全避免线程,例如。 G。 HttpClient.GetByteArrayAsync
或 HttpClient.GetStreamAsync
+ Stream.CopyToAsync
.
E. g.:
HttpClient client = new HttpClient(); // maybe configure it
async Task ProcessRow(Row row) // put here the correct type
{
try
{
var str = await client.GetStringAsync(row[address]);
AppendTextBox(str, txtBoxResponse);
}
catch (HttpRequestException ex)
{
AppendTextBox(row["ssub_msisdn"] + ", Error: " + ex.Message, txtBoxResponse);
}
}
var tasks = dt.AsEnumerable().Select(row => ProcessRow(row));
await Yask.WhenAll(tasks);