简体   繁体   中英

How to handle single result from multiple threads?

Let's say i have few file formats i can read from. eg. xml, yaml and json. For each format i have specific reader but i do not know until runtime which file was placed so i try to read file with all of these readers. This whole process is currently async.

All i want is a proper way to return only 'FileReaderTask' which completed with result.

So far i came with this but i don't like it too much. Especially the part where i return null

    public async Task<ReadResponse> Read(string id)
{
  var readerDetails = _readerDetailsRepository.GetAll();
  var tasks = readerDetails.Select(readerDetail => _reader.ReadAsync(readerDetail, id)).ToList();

  foreach (var result in await Task.WhenAll(tasks))
  {
    if (!string.IsNullOrEmpty(result)) // only one will have the response !
    {
      return await HandleResponse(_jsonConverter.Convert<ReadResponse>(result), id);
    }
  }
  return null; // ?? seems pretty bad
}

Your process is asynchronous, but it is not using multiple threads.In this case it is a good thing, because the threads reading the same file would be competing with each other.

Your current approach uses WhenAll , which waits for all tasks to complete before picking the result. This is fine, assuming that all failing tasks complete first. You don't have to wait for all tasks, and process them as they complete instead:

var tasks = readerDetails.Select(readerDetail =>
    _reader.ReadAsync(readerDetail, id).ConfigureAwait(false)
).ToList();
foreach (var task in tasks) {
    var result = await task;
    if (!string.IsNullOrEmpty(result)) {
        return await HandleResponse(_jsonConverter.Convert<ReadResponse>(result), id);
    }
}

The loop awaits individual tasks one-by-one, so if the successful task completes ahead of an unsuccessful one, your code wouldn't wait for completion of the remaining tasks before handling the response.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM