我目前正在做一个项目,在现有的ASP.Net MVC网站和我的公司正在使用的文件托管服务之间建立一个集成。典型的用例是:
托管服务可以处理并发调用,我发现在任务中执行每个API调用(参见下面的示例)会带来相当大的改进。
private void RetrieveDocuments(DocumentIdentifier[] identifiers, List<FileHostResult> results)
{
var tasks = identifiers.Select(x => RetrieveDocument(results, x)).ToArray();
Task.WaitAll(tasks);
}
private Task RetrieveDocument(List<FileHostResult> results, DocumentIdentifier x)
{
return Task.Run(() =>
{
var result = GetFileHostResultFromFileHost(x.ExternalIdentifier);
lock (results)
{
results.Add(result);
}
});
}
我的问题是,是否有更好的方法来做到这一点,或者是否有任何潜在的陷阱,我可能会遇到?(例如,锁定服务器资源等)。
编辑1:我没有发布GetFileHostResultFromFileHost的代码,因为我实际上没有任何权限来更改它。它基本上是一个在库中实现的方法调用,我无法更改。
编辑2:澄清。我主要关心的是避免损害网站当前的用户体验。为此,我希望确保在ASP.net mvc之外并发运行任务不会锁定站点。
发布于 2018-06-09 12:17:20
为此,您应该使用Microsoft的Reactive Framework。它非常适合于这种处理。
代码如下:
IObservable<FileHostResult> query =
from i in identifiers.ToObservable()
from r in Observable.Start(() => GetFileHostResultFromFileHost(i.ExternalIdentifier))
select r;
IList<FileHostResult> results = query.ToList().Wait();
就这样。它适当地将代码安排在最优的线程数上。
如果你想要可等待的代码,你可以这样做:
IObservable<FileHostResult> query =
from i in identifiers.ToObservable()
from r in Observable.Start(() => GetFileHostResultFromFileHost(i.ExternalIdentifier))
select r;
IList<FileHostResult> results = await query.ToList();
它真的非常简单,很容易编码。
NuGet "System.Reactive“,然后将using System.Reactive.Linq;
添加到代码中。
发布于 2018-06-09 05:51:24
如果不看其余的源代码,就很难给出好的建议。但根据我所看到的,我会建议这样一种方法:
private void RetrieveDocuments(DocumentIdentifier[] identifiers, List<FileHostResult> results)
{
results.AddRange(identifiers.AsParallel().Select(x => RetrieveDocument(x)));
}
private FileHostResult RetrieveDocument(DocumentIdentifier x)
{
var result = GetFileHostResultFromFileHost(x.ExternalIdentifier);
return result;
}
这种方法的优点是:
Task.Run
-让AsParallel
为您处理。results
列表-让AsParallel
和Select
为您处理<代码>H210<代码>F211您可能还希望增加您有权访问的连接的。
不过老实说,我认为你应该考虑那些根本不需要新的并行Task
**s的方法--可能是通过使用http下载调用,这样你就可以在没有线程开销的情况下运行 [in parallel](https://stackoverflow.com/questions/19383910/paralell-foreach-with-httpclient-and-continuewith) 。**
https://stackoverflow.com/questions/50768473
复制相似问题