我正在运行一个定期滚动到网址列表的流程,以测试这些网站的效果。我的主程序基本上是一个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”函数执行它在tin上所说的内容,将http超时值设置为取消令牌的一半,以便在调用取消令牌之前HTTP请求应该消失,并生成否定结果。我添加了取消令牌以尝试处理我的问题,如下所示。
我让它运行了很长时间 - 首先,一切运行良好,但最终(通过定期runTest()调用的数百次,如果不是更多的迭代),似乎其中一个任务被卡住并且取消令牌不是' t调用,卷曲测试过程实际上被卡住了。
除了提取哪些URL有问题(并且它们都是有效的)之外,还可以采取哪些措施来诊断出现了什么问题?或者我是否完全错误地构建了我的并行Curls? (我很欣赏我可以将新的Curls实例化为已经从上一轮完成的URL并让悬挂的一个悬挂,而不是在开始新批次之前等待它们全部完成,但我并不担心这个效率增益)。
答案 0 :(得分:3)
取消时没有自动化。您必须检查取消状态并结束执行或调用CancellationToken.ThrowIfCancellationRequested
以执行取消。如果请求取消,CancellationToken
会告诉您;取消本身必须由您完成。
以下行是您的问题:
Task t = new Task(() => easy.Perform(), cts.Token);
您正在将令牌传递给任务构造函数。如果在任务开始之前发生取消,这将对您有所帮助。任务启动后,执行的方法负责取消。 easy.Perform()
不知道您的取消令牌,因此永远无法确定是否要求取消。因此,它将运行到最后。
您需要在任务执行期间定期检查取消令牌,以达到您想要的效果。