当您在 C# 任务等待者上调用“OnComplete()”时,如何等待 OnCompleted 调用中给出的新作业
本文关键字:等待 调用 OnCompleted 何等待 作业 新作业 任务 OnComplete | 更新日期: 2023-09-27 18:18:57
我的Controller
对象使用 Renci.SshNet 通过 SSH 调用 MySQL 数据库,由于我连接到多个数据库,我转向多线程,函数af.FetchAll()
返回一个DataSet
,所有这些都被添加到列表DataList<DataSet>
,然后我要求所有任务完成,然后我会给我的 DataList
to writer 对象以将其保存到 CSV 文件, 问题是:尽管我要求任务完成foreach (Task t in taskList) t.Wait();
,但文件编写器尝试访问它时,awaiter.OnCompleted(() =>..etc
中的代码仍在更新DataList
,我如何确保等待者在我继续将"DataList"写入文件之前完成执行
public void Query()
{
List<QueryValue> QueriesList = quryValLister.GetQueriesList();
List<ConnectionValues> ConnectionsList = concValLister.GetConnectionList();
// iterating over servers
List<Task> taskList = new List<Task>();
foreach (ConnectionValues obj in ConnectionsList)
{
Controller af = new Controller(obj, QueriesList);
Task<DataSet> taskDataResult = Task.Run (() => af.FetchAll());
taskList.Add(taskDataResult);
var awaiter = taskDataResult.GetAwaiter();
awaiter.OnCompleted(() =>
{
DataSet temp = awaiter.GetResult();
if (temp != null)
{
MyDataList.Add(temp);
}
});
}
foreach (Task t in taskList) t.Wait();
}
您不应该在常规代码中使用GetAwaiter
。
如果要异步编写此内容,可以执行以下操作:
public Task QueryAsync()
{
List<QueryValue> QueriesList = quryValLister.GetQueriesList();
List<ConnectionValues> ConnectionsList = concValLister.GetConnectionList();
// iterating over servers
var tasks = ConnectionsList
.Select(obj => Task.Run(() => new Controller(obj, QueriesList).FetchAll()));
MyDataList.AddRange(await Task.WhenAll(tasks));
}
或者,如果要同步编写它:
public void Query()
{
List<QueryValue> QueriesList = quryValLister.GetQueriesList();
List<ConnectionValues> ConnectionsList = concValLister.GetConnectionList();
// iterating over servers
var tasks = ConnectionsList
.Select(obj => Task.Run(() => new Controller(obj, QueriesList).FetchAll()))
.ToArray();
Task.WaitAll(tasks);
foreach (var task in tasks)
MyDataList.Add(task.Result);
}
请注意,同步版本中的错误处理是不同的;异常包装在 AggregateException
中。