When you call `OnCompleted ()` on an awaiter C # task, how do you wait for a new task specified inside an OnCompleted call?

My object Controllermakes calls to MySQL DB via SSH using Renci.SshNet, since I connect to several databases, I turned to multithreading, the function af.FetchAll()returns a DataSet, all of which are added to the list DataList<DataSet>, then I will ask all the tasks to be completed, then I will pass the object DataListfor the recording object to save it in a CSV file. The problem is this: the code inside awaiter.OnCompleted(() =>..etcis still updating DataListwhile the file writer is trying to access it, despite the fact that I asked the task to complete foreach (Task t in taskList) t.Wait();, how can I make sure awaiter has finished execution before I continue and write "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();
    }
+3
source share
1 answer

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.

+6

Source: https://habr.com/ru/post/1675434/


All Articles