任务持久性 C#



我很难让我的任务保持持久并从 WCF 服务无限期运行。我可能这样做的方式错误,并愿意接受建议。

我有一个任务,它开始处理放入 BlockingCollection 的任何传入请求。据我了解,GetConsumingEnumerable() 方法应该允许我在数据到达时持久地提取数据。它本身没有问题。我能够处理数十个请求,而不会出现一个错误或缺陷,使用 Windows 表单填写请求并提交它们。一旦我对这个过程充满信心,我就通过asmx Web服务将其连接到我的站点,并使用jQuery ajax调用来提交请求。

网站根据提交的 URL 提交请求,Web 服务从该 URL 下载 html 内容,并在内容中查找其他 URL。然后,它继续为找到的每个 url 创建一个请求,并将其提交给 BlockingCollection。在 WCF 服务中,如果应用程序处于联机状态(即任务已启动),它将通过 Parallel.ForEach 使用 GetConsumingEnumerable 拉取请求并处理请求。

这适用于前几个提交,但随后任务会意外停止。当然,这比我在测试中模拟的请求多 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。如果需要更多信息,请告诉我。

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

但是,有一些

事情可能会出错:

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

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

相关内容

  • 没有找到相关文章

最新更新