1

我很难让我的任务保持持久性并从 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。如果需要更多信息,请告诉我。

4

2 回答 2

1

您显示的代码本身是正确的。

但是,有一些事情可能会出错:

  • 如果发生异常,您的任务将停止(当然)。尝试添加一个 try-catch 并记录异常。
  • 如果您在托管环境(ASP.NET、WCF、SQL Server)中启动工作线程,则宿主可以任意(没有理由)决定关闭任何工作进程。例如,如果您的 ASP.NET 站点在一段时间内处于非活动状态,则应用程序将关闭。我刚才提到的主机不是为了运行自定义线程而设计的。使用专用应用程序 (.exe) 甚至 Windows 服务,您可能会获得更大的成功。
于 2012-05-27T13:31:02.093 回答
0

事实证明,这个问题的原因是 WCF 绑定配置。该任务突然停止,因为 WCF 由于打开超时而终止了连接。打开超时设置是请求在超时之前等待服务打开连接的时间。在某些情况下,它达到了 10 个最大连接的限制,并导致传入连接被备份以等待连接。我确保在事务完成后关闭了与主机的所有连接 - 所以我放弃了增加最大连接数和打开超时期限。在此之后 - 它运行完美。

于 2012-05-28T18:47:23.300 回答