Добавить в словарь результаты из WaitAll

#c# #asynchronous

#c# #асинхронный

Вопрос:

Я хочу сохранить результаты асинхронных запущенных задач в частном словаре. Когда я использую add, я получаю исключение с нулевой ссылкой. Что я должен изменить, чтобы правильно заполнить словарь?

Вот мой код, который я получил до сих пор:

  private Dictionary<string, long> _filesDictionary;

public void GetFiles(string pathToFolder)
{
    var allDirectories = Directory.EnumerateDirectories(pathToFolder, "*", SearchOption.AllDirectories);
   allDirectories.ToList().Add(pathToFolder);
   foreach (var dir in allDirectories)
    {
        FolderReading(dir);

    }
}

public void FolderReading(string folderPath)
{
    string[] fileSystemEntries = Directory.GetFileSystemEntries(folderPath);
    if (fileSystemEntries.Count() != 0)
    {
        List<Task> tasks = new List<Task>();
        foreach (var filePath in fileSystemEntries.OrderBy(s => s))
        {
            Task task = Task.Run(() => CountSizes(filePath));
            tasks.Add(task);
        }
        Task.WaitAll(tasks.ToArray());
    }
}

private void CountSizes(string filePath)
{
    byte[] fileData = null;
    int arraySum = 0;
    string fileName = Path.GetFullPath(filePath);

    using (FileStream fs = File.OpenRead(filePath))
    {
        using (BinaryReader binaryReader = new BinaryReader(fs))
        {
            fileData = binaryReader.ReadBytes((int)fs.Length);
        }
    }
    foreach (byte b in fileData)
    {
        arraySum  = b;
    }
    Console.WriteLine($"{fileName} ArraySum{arraySum}; ThreadNum:{Thread.CurrentThread.ManagedThreadId}");
    _filesDictionary.Add(fileName, arraySum);

}
  

Ответ №1:

You’re _filesDictionary никогда не создается, только объявляется, что означает, что в этом случае он всегда будет иметь значение по умолчанию null . Где-то в вашем коде вам нужно присвоить ему значение. Обычно это делается в конструкторе класса, но вы также можете сделать это прямо в объявлении.

Конструктор:

 _filesDictionary = new Dictionary<string, long>();
  

Объявление:

 private Dictionary<string, long> _filesDictionary = new Dictionary<string, long>();
  

Редактировать: только сейчас заметил, что вы используете несколько задач для добавления в словарь, но имейте в виду, что defualt Dictionary не является полностью потокобезопасным. Это означает, что чтение из словаря из нескольких задач (возможно, в разных потоках выполнения) в порядке, но запись в него невозможна, поскольку это может привести к скачкам данных и недопустимым добавлениям. Вместо этого вам нужно будет использовать .NET’s ConcurrentDictionary