Почему моя задача не отменяется?

Я запускаю процесс, который периодически скручивается в список URL-адресов, чтобы проверить производительность этих сайтов. Моя основная программа - это цикл do ... sleep ... while, который вызывает функцию runTest () каждые N секунд, с прерыванием клавиатуры, чтобы убить его. По сравнению с основами мой код выглядит следующим образом:

public void runTest()
{
   if(isRunning)
   {
      return; //Plus some logging that one or more of the tests hasn't completed
   }
   try {
       isRunning = true;
       Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL);
       CancellationTokenSource cts = new CancellationTokenSource(httpTimeoutValueMs * 2);
       foreach (var url in urls)
            taskList.Add(doAsyncCurls(url, cts))
       List<CurlResults> listOfResults = Task.WhenAll(taskList.Select(x => x)).Result.ToList();
       taskList.Clear();
  }
  catch {/*Some exception handling code*/}
  finally { 
    isRunning = false; 
    Curl.GlobalCleanup();
  }
}
private static async Task<CurlResults> doAsyncCurls(string url, CancellationTokenSource cts)
{
    try
    {
      /*Initiate a Curl using libCurl*/
      Easy easy = new Easy();
      easy.SetOpt(CURLoption.CURLOPT_URL, url);
      easy.SetOpt(CURLoption.CURLOPT_DNS_CACHE_TIMEOUT, 0); //Disables DNS cache
      easy.SetOpt(CURLoption.CURLOPT_CONNECTTIMEOUT, httpTimeoutValueMs / 1000); //20sec timeout

      Task t = new Task(() => easy.Perform(), cts.Token);
      t.Start();
      await t;
      return new CurlResults(/*valid results parameters*/);
    } 
    catch (TaskCanceledException)
    { /*Cancellation token invoked*/
        return new CurlResults(/*Invalid results parameters*/);
    }
    catch (Exception e)
    { /*Other exception handling*/ 
        return new CurlResults(/*Invalid results parameters*/);
    }

Функция «doAsyncCurl» делает то, что говорит на жестяной коробке, устанавливая значение тайм-аута http, равное половине значения токена отмены, так что HTTP-запрос должен испариться до вызова токена отмены и генерировать отрицательный результат. Я добавил токен отмены, чтобы попытаться решить мою проблему, как показано ниже.

Я оставляю это запущенным целую вечность - для начала все работает хорошо, но в конце концов (сотни, если не больше итераций через периодический вызов runTest ()) кажется, что одна из задач застревает и токен отмены не вызывается, и процесс тестирования завитка эффективно застрял.

Помимо определения того, какие URL-адреса являются проблематичными (и все они действительны), что можно сделать для диагностики неисправности? Или я с самого начала построил свои параллельные кудри совершенно неправильно? (Я ценю, что могу создать новые Curls для URL-адресов, которые закончили с предыдущего раунда, и оставить зависший один на один, вместо того, чтобы ждать, пока все они закончат, прежде чем начать новую партию, но меня не беспокоит эта эффективность усиление).

Ответы на вопрос(1)

Ваш ответ на вопрос