gpt4 book ai didi

c# - 每个循环的任务工厂带有await

转载 作者:行者123 更新时间:2023-12-03 02:28:51 25 4
gpt4 key购买 nike

我是任务新手,对使用有疑问。 Task.Factory 是否会触发 foreach 循环中的所有项目或在“await”处阻塞,基本上使程序成为单线程?如果我正确地考虑了这一点,则 foreach 循环将启动所有任务和 .GetAwaiter().GetResult();阻塞主线程,直到最后一个任务完成。

另外,我只是想要一些匿名任务来加载数据。这是正确的实现吗?我不是指异常处理,因为这只是一个示例。

为了清楚起见,我正在从外部 API 将数据加载到数据库中。这个使用的是 FRED 数据库。 ( https://fred.stlouisfed.org/ ),但我有几个我会点击来完成整个传输(可能是 200k 数据点)。一旦完成,我就会更新表格、刷新市场计算等。其中一些是实时的,一些是日终的。我还想说,我目前在 docker 中一切正常,但一直在努力使用任务来更新代码以提高执行力。

class Program
{
private async Task SQLBulkLoader()
{

foreach (var fileListObj in indicators.file_list)
{
await Task.Factory.StartNew( () =>
{

string json = this.GET(//API call);

SeriesObject obj = JsonConvert.DeserializeObject<SeriesObject>(json);

DataTable dataTableConversion = ConvertToDataTable(obj.observations);
dataTableConversion.TableName = fileListObj.series_id;

using (SqlConnection dbConnection = new SqlConnection("SQL Connection"))
{
dbConnection.Open();
using (SqlBulkCopy s = new SqlBulkCopy(dbConnection))
{
s.DestinationTableName = dataTableConversion.TableName;
foreach (var column in dataTableConversion.Columns)
s.ColumnMappings.Add(column.ToString(), column.ToString());
s.WriteToServer(dataTableConversion);
}

Console.WriteLine("File: {0} Complete", fileListObj.series_id);
}
});
}
}

static void Main(string[] args)
{
Program worker = new Program();
worker.SQLBulkLoader().GetAwaiter().GetResult();
}
}

最佳答案

您等待从 Task.Factory.StartNew 返回的任务确实使其有效地成为单线程。您可以通过这个简短的 LinqPad 示例看到对此的简单演示:

for (var i = 0; i < 3; i++)
{
var index = i;
$"{index} inline".Dump();
await Task.Run(() =>
{
Thread.Sleep((3 - index) * 1000);
$"{index} in thread".Dump();
});
}

随着循环的进行,我们等待的时间会减少。输出为:

0 inline
0 in thread
1 inline
1 in thread
2 inline
2 in thread

如果您删除 StartNew 前面的 await,您将看到它并行运行。正如其他人提到的,您当然可以使用 Parallel.ForEach,但是为了演示手动执行此操作,您可以考虑这样的解决方案:

var tasks = new List<Task>();

for (var i = 0; i < 3; i++)
{
var index = i;
$"{index} inline".Dump();
tasks.Add(Task.Factory.StartNew(() =>
{
Thread.Sleep((3 - index) * 1000);
$"{index} in thread".Dump();
}));
}

Task.WaitAll(tasks.ToArray());

现在请注意结果如何:

0 inline
1 inline
2 inline
2 in thread
1 in thread
0 in thread

关于c# - 每个循环的任务工厂带有await,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53981438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com