线程池中有大量线程处于等待状态,导致性能问题



我的应用程序通过http连接到大量客户端,从这些客户端下载数据,并在收到这些结果时处理数据。每个请求都在一个单独的线程中发送,这样主线程就不会被占用。

我们已经开始遇到性能问题,似乎这些问题主要与ThreadPool中的大量线程有关,这些线程正在等待从这些请求中获取数据。我知道在。net 4.5中,我们有asyncawait来解决相同类型的问题,但我们仍然使用。net 3.5。

在不同的线程中发送这些请求的最佳方式是什么,而不是让该线程保持活跃,而它所做的一切都是等待请求回来?

你可以在。net 3.5中使用异步操作,只是不像。net 4.5那么方便。大多数IO方法都有BeginX/EndX方法对,这是X方法的异步等效。这被称为异步编程模型(APM)。

例如,您可以使用Stream.BeginReadStream.EndRead而不是Stream.Read

实际上,. net 4.5中的许多异步IO方法只是围绕Begin/End方法的包装。

如果你不能使用。net 4。x和async/await,您仍然可以使用IEnumeratoryield实现类似的行为。它允许使用伪同步线性代码流与Begin/End风格的回调,包括语句像using, try/finally, while/for/foreach等。但是不能使用try/catch

有一些异步枚举器驱动的实现,例如Jeffrey Richter的AsyncEnumerator

我过去用过类似下面的东西:

class AsyncIO
{
    void ReadFileAsync(string fileName)
    {
        AsyncOperationExt.Start(
            start => ReadFileAsyncHelper(fileName, start),
            result => Console.WriteLine("Result: " + result),
            error => Console.WriteLine("Error: " + error));
    }
    static IEnumerator<object> ReadFileAsyncHelper(string fileName, Action nextStep)
    {
        using (var stream = new FileStream(
            fileName, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 1024, useAsync: true))
        {
            IAsyncResult asyncResult = null;
            AsyncCallback asyncCallback = ar => { asyncResult = ar; nextStep(); };
            var buff = new byte[1024];
            while (true)
            {
                stream.BeginRead(buff, 0, buff.Length, asyncCallback, null);
                yield return Type.Missing;
                int readBytes = stream.EndRead(asyncResult);
                if (readBytes == 0)
                    break;
                // process the buff
            }
        }
        yield return true;
    }
}
// ...
// implement AsyncOperationExt.Start
public static class AsyncOperationExt
{
    public static void Start<TResult>(
        Func<Action, IEnumerator<TResult>> start,
        Action<TResult> oncomplete,
        Action<Exception> onerror)
    {
        IEnumerator<TResult> enumerator = null;
        Action nextStep = () =>
        {
            try
            {
                var current = enumerator.Current;
                if (!enumerator.MoveNext())
                    oncomplete(current);
            }
            catch (Exception ex)
            {
                onerror(ex);
            }
            enumerator.Dispose();
        };
        try
        {
            enumerator = start(nextStep);
        }
        catch (Exception ex)
        {
            onerror(ex);
            enumerator.Dispose();
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新