运行线程慢慢减少

时间:2017-09-28 09:13:05

标签: c# multithreading performance asynchronous

我有一个我想同时运行的进程。该进程使用HttpClient请求并处理json文件。

它开始工作非常快,然后逐渐减慢。我将所有衍生的任务保存到List<Task>。如果我在执行开始后立即设置了一个断点,那么任务列表中大约有98个任务。在5-10分钟之后,处理进行得非常慢,当我设置断点时,只有大约60个任务在运行,但处理速度非常慢。可能是初始速度的10-20%。

RAM使用情况看起来很好。在开始时,我的CPU运行在90%左右,但是在5-10分钟后它下降到50%,处理的记录数量非常低。

我使用SemaphoreSlim来控制正在运行的进程数。

static SemaphoreSlim semaphore = new SemaphoreSlim(100, 100);

这就是我产生任务的方式。我正在读取一个非常大的文件(数百万条记录),所以这个while循环需要无限期地运行而不会放慢速度。

List<Task> taskList = new List<Task>();
int currentRow = 0;

using (StreamReader sReader = new StreamReader(processPath + fileName))
{
    string dataLine;
    while ((dataLine = sReader.ReadLine()) != null)
    {

        CancellationTokenSource tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;

        taskList.RemoveAll(x => x.IsCompleted);

        semaphore.Wait();
        Interlocked.Increment(ref currentRow);

        string domain = dataLine.Split(',')[0];
        int row = currentRow;

        taskList.Add(Task.Run(() => GetArchiveCounts(domain, row, token)));

        tokenSource.CancelAfter(TimeSpan.FromSeconds(180));
    }
}
Task.WhenAll(taskList).Wait();

我在GetArchiveCounts()方法中执行IO。我正在传递取消令牌并将其设置为180秒后自动取消,以避免任何线程被永久锁定并导致减速。当我设置断点时,我看不到任何状态为已取消的任务。

我在GetArchiveCounts()方法中释放信号量:

public static async Task GetArchiveCounts(string domain, int row, CancellationToken token)
{
    bool done = false;

    while (token.IsCancellationRequested == false && done == false)
    {
        using (HttpClient client = new HttpClient(httpClientHandler))
        {
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            HttpResponseMessage response = await client.GetAsync(requestUrl, token);

            if (response.IsSuccessStatusCode)
            {
                // omitted code, I just process result here
            }
        }
        done = true;
    }
    semaphore.Release();
}

我在这里使用的取消模式感觉不对,我猜这可能是我的问题的原因,但我不确定。由于我没有收到任何错误,我很难搞清楚最新情况。我认为应该可以无限期地保持前几百个处理记录的速度,但我无法弄清楚我的代码中应该归咎于什么。

谁能看到我做错了什么?

0 个答案:

没有答案