在IIS 7中使用TPL - 处理任务/线程/请求

时间:2013-03-20 16:15:28

标签: c# multithreading wcf iis-7 task-parallel-library

原谅标题,我不太确定如何说出我要找的东西,或者我是否知道我在寻找什么。

我有一个正在运行的服务,它同时需要大量的请求。另外,在服务中,我必须向外部服务发出一定数量(通常是10-15)的请求,这是我并行运行的。这段代码如下所示

        Task<IResponse>[] tasks = new Task<IResponse>[Adapters.Count];
        for(int i = 0; i < Adapters.Count;i++)
        {
            IAdapter adapter = Adapters[i];

            Func<IResponse> makeExternalHttpRequest= () => adapter.MakeExternalHttpRequest(element, mappings);
            tasks[i] = Task.Factory.StartNew<IResponse>(() =>
                {
                    try
                    {
                        var result = makeExternalHttpRequest();
                        if (!token.IsCancellationRequested)
                        {
                            return result;
                        }
                    }catch(Exception exception)
                    {

                    }

                    return null;

                }, token);
        };
        var timeout = ...some timeout value
        Task.WaitAll(tasks,timeout, token);
        tokenSource.Cancel();

        for (int i = 0; i < tasks.Length; i++)
        {
            if (tasks[i].Result != null)
            {
                if (tasks[i].IsCompleted)
                {
                    results.Add(tasks[i].Result);
                }
            }
        }

在过去的6-7个月里,一切似乎都按照我的预期运行,然后昨天,服务器停机了,我从系统管理员那里收到了以下信息。

enter image description here

如果您注意到突出显示的区域,则它在经过的时间内非常大。

我猜这有助于服务器停机的原因,但我们仍在调查发生了什么。

对于发生了什么以及接下来的步骤应该是什么?

1 个答案:

答案 0 :(得分:0)

我认为您接下来的步骤应该是收集更多信息。编写代码的方式,您的请求将在超时到期后立即返回(或者所有任务完成后,以先到者为准)。其他任务将在后台自行运行完成,假设makeExternalHttpRequest()方法最终超时,它们将在自己的时间内完全停止。

您的取消令牌没有做任何有用的事情,因为代码将在其上方的行上阻止。

我要做的是弄清楚哪个外部请求花费的时间最长,并在发生这种情况时记录警告。那么至少你会有更好的信息来了解正在发生的事情。请参阅此pesudo代码:

(上面某处,创建一个记录器和System.Diagnostics.Stopwatch

              try
                {
                    var result = makeExternalHttpRequest();
                    if(stopwatch.Elapsed > SomeUnreasonableTimespan) 
                          logger.Warn("Task exceeded reasonable execution period." + TaskData);

                    if (!token.IsCancellationRequested)
                    {
                        return result;
                    }
                }catch(Exception exception)
                {

                }

                return null;

作为一般性评论,我发现这条信息最有用:

  

在过去的6-7个月里,一切似乎都按照我的预期运行,然后昨天,服务器停机了,我从系统管理员那里收到了以下信息。

这意味着问题可能与您的代码无关,但与其他内容有关。当我进行故障排除时,我倾向于忽略那些没有改变的事情,并专注于那些事情。服务器不时会崩溃。您需要担心的是他们大多数时间都满足您的要求吗?如果是这样,那么我不会太担心这段代码。