我正在运行一个进程,定期卷曲到 URL 列表以测试这些网站的性能。我的主程序基本上是一个 do...sleep...while 循环,每 N 秒调用一个函数 runTest(),并用键盘中断来终止它。精简到基础知识,我的代码如下:
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() 调用进行数百次甚至更多迭代)似乎其中一个任务被卡住并且取消令牌没有被调用,并且curl测试过程被有效卡住。
除了找出哪些 URL 有问题(而且它们都是有效的 URL)之外,还可以采取什么措施来诊断出了什么问题?或者我一开始就完全错误地构造了我的平行卷发? (我很高兴我可以将新的 Curls 实例化为上一轮已完成的 URL,并将挂起的 URL 悬空,而不是等待它们全部完成后再开始新批次,但我并不担心这种效率获得)。
取消不会自动发生。您必须检查取消状态并结束执行或调用CancellationToken.ThrowIfCancellationRequested
执行取消操作。这CancellationToken
会告诉你if要求取消;取消itself必须由你来完成。
以下行是您的问题:
Task t = new Task(() => easy.Perform(), cts.Token);
您正在将令牌传递给任务构造函数。如果您取消预订,这将对您有所帮助before任务开始。一旦任务开始,执行的方法负责取消。easy.Perform()
不知道您的取消令牌,因此永远无法确定是否请求取消。因此,它将运行到最后。
您需要在任务执行期间定期检查您的取消令牌以实现您想要的目的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)