My Controller
object makes calls to a MySQL DB over SSH using Renci.SshNet, since i am connecting to several DB, i turned to multithreading, the function af.FetchAll()
return a DataSet
, all of which are added to a list DataList<DataSet>
, i then ask all tasks to complete, then i will give my DataList
to writer object to save it to CSV file, The problem is: The code inside the awaiter.OnCompleted(() =>..etc
is still updating the DataList
while the file writer is trying to access it, despite me asking the task to complete foreach (Task t in taskList) t.Wait();
, how can i make sure that the awaiter finished executing before i go on and write the 'DataList' to file
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();
}
答案 0 :(得分:6)
您不应该在常规代码中使用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
。