我很难让我的任务保持持久性并从 WCF 服务无限期地运行。我可能以错误的方式这样做,并愿意接受建议。
我有一个任务开始处理放入 BlockingCollection 的任何传入请求。据我了解,GetConsumingEnumerable() 方法应该允许我在数据到达时持续提取数据。它本身没有问题。我能够处理数十个请求,而没有一个错误或缺陷,使用 Windows 表单填写请求并提交它们。一旦我对这个过程充满信心,我就会通过 asmx Web 服务将它连接到我的站点,并使用 jQuery ajax 调用来提交请求。
站点根据提交的 url 提交请求,Web 服务从 url 下载 html 内容并在内容中查找其他 url。然后它继续为它找到的每个 url 创建一个请求,并将其提交给 BlockingCollection。在 WCF 服务中,如果应用程序处于联机状态(即任务已启动) - 它使用 GetConsumingEnumerable 通过 Parallel.ForEach 拉取请求并处理请求。
这适用于前几次提交,但随后任务意外停止。当然,这比我在测试中模拟的请求多 10 倍——但我预计它只会节流。我相信问题出在我启动任务的方法中:
public void Start()
{
Online = true;
Task.Factory.StartNew(() =>
{
tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 20;
options.CancellationToken = token;
try
{
Parallel.ForEach(FixedWidthQueue.GetConsumingEnumerable(token), options, (request) =>
{
Process(request);
options.CancellationToken.ThrowIfCancellationRequested();
});
}
catch (OperationCanceledException e)
{
Console.WriteLine(e.Message);
return;
}
}, TaskCreationOptions.LongRunning);
}
我曾考虑将其移至 WF4 服务中,然后将其连接到工作流中并使用工作流持久性,但除非必要,否则我不愿意学习 WF4。如果需要更多信息,请告诉我。