C# 如何处理来自多个线程的单个结果?

C# 如何处理来自多个线程的单个结果?,c#,.net,task-parallel-library,C#,.net,Task Parallel Library,比如说,我可以读取的文件格式很少。例如xml、yaml和json。 对于每种格式,我都有特定的读卡器,但直到运行时我才知道放置了哪个文件,所以我尝试使用所有这些读卡器读取该文件。 整个过程目前是异步的 我所需要的是一种只返回“FileReaderTask”的正确方法,该任务以结果完成 到目前为止,我带了这个,但我不太喜欢它。 尤其是返回null的部分 public async Task<ReadResponse> Read(string id) { var readerD

比如说,我可以读取的文件格式很少。例如xml、yaml和json。 对于每种格式,我都有特定的读卡器,但直到运行时我才知道放置了哪个文件,所以我尝试使用所有这些读卡器读取该文件。 整个过程目前是异步的

我所需要的是一种只返回“FileReaderTask”的正确方法,该任务以结果完成

到目前为止,我带了这个,但我不太喜欢它。 尤其是返回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
}
公共异步任务读取(字符串id)
{
var readerDetails=_readerDetailsRepository.GetAll();
var tasks=readerDetails.Select(readerDetail=>_reader.ReadAsync(readerDetail,id)).ToList();
foreach(var导致等待任务。WhenAll(任务))
{
if(!string.IsNullOrEmpty(result))//只有一个会有响应!
{
返回wait HandleResponse(_jsonConverter.Convert(result),id);
}
}
返回null;//?似乎很糟糕
}

您的进程是异步的,但它不使用多个线程。在这种情况下,这是一件好事,因为读取同一文件的线程将相互竞争

您当前的方法使用
whalll
,它在选择结果之前等待所有任务完成。这很好,假设所有失败的任务都首先完成。您不必等待所有任务,而是在任务完成时进行处理:

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);
    }
}
var tasks=readerDetails.Select(readerDetail=>
_reader.ReadAsync(readerDetail,id).ConfigureAwait(false)
).ToList();
foreach(任务中的var任务){
var结果=等待任务;
如果(!string.IsNullOrEmpty(结果)){
返回wait HandleResponse(_jsonConverter.Convert(result),id);
}
}

循环一个接一个地等待单个任务,因此,如果成功的任务在不成功的任务之前完成,那么代码不会在处理响应之前等待剩余任务的完成。

我是Java程序员,您可以使用Thread.join()来等待所有线程的完成。我知道C#有一个等价物,你可以研究一下。这是不是意味着你让每个读者都去看每个文件,并期望除一个以外的所有人都失败?@dlatikay:我也明白这一点。蛮力approach@Juan:当然C#有Thread.Join(),但那是错误的层。任务已经在线程之上提供了一个抽象。@ThomasWeller Ok为什么不应该在线程池之外的不同线程上调度所有任务?当然,算法会等到它们全部完成finished@ThomasWeller由于资源争用:所有线程将在同一时间读取同一文件。它们读取的是一个字符串。字符串是不可变的。所有线程都可以同时读取嗯,好的。我们实际上不知道有什么类型的重源。@dasblinkenlight该资源是json字符串。