[英]Using CancellationToken to quit an async method after a timeout
既然 the.abort() 已被弃用,使用取消标记是关闭异步线程的推荐方法,但我不知道如何在超时后执行此操作。 这只是一个逻辑问题,我很难想通......
我正在以编程方式安装 a.network 驱动器,但我似乎无法弄清楚如何使用取消令牌使整个操作在 x 时间后退出,所以它不仅仅是阻塞线程,如果它出于任何原因挂起(如果找不到地址,操作通常会停止,而不是停止或崩溃)。
tokensource 的代码是这样的:
using var cts = new CancellationTokenSource();
cts.CancelAfter(2000); //timeout value
Task<bool> attempt_mounting = Utility.Windows.System.PerformTargetLocationMounting(ADDRESS, "X", cts.Token);
primary_connection_success = await attempt_mounting;
超时后我想取消的代码是这样的:
internal static async Task<bool> PerformTargetLocationMounting(string address, string drive, CancellationToken ct)
{
Console.WriteLine("[*] Attempting target mounting");
return await Task.Run(async () =>
{
try
{
ct.ThrowIfCancellationRequested(); //currently unsure on what to do with this
await Task.Delay(5000).ConfigureAwait(false); //and this is just to force it to cancel so I can try things out
NetworkDrive.MapNetworkDrive(drive, address);
return true;
}
catch
{
Console.WriteLine("[!] Untraced mounting error.");
return false;
}
});
}
我不知道如何获得它,这样我就可以调用 cancellationtoken 而不必使用 while true 连续轮询,并且由于 map.network 驱动器肯定不是我想要连续调用的东西,我不确定如何go关于这个......
您需要将CancellationToken
传递给需要取消的任何方法 - 在本例中为NetworkDrive.MapNetworkDrive
。
但是,该方法很可能不会使用取消令牌; 许多与文件系统相关的 API 不允许取消。 在这种情况下,您有两个选择:
WaitAsync
或类似的方法来取消任务的等待,并让MapNetworkDrive
完成或不完成。您希望以非合作方式使用CancellationToken
。 这不是通常使用CancellationToken
的方式。 由于您调用的是不接受CancellationToken
的 API,因此您无法合作终止此 API。因此,您的问题没有完美而干净的解决方案。 在单独的进程中调用 API 然后在运行时间过长的情况下终止进程,这是一种仅保留进程完整性的解决方案,但它不能保证整个应用程序的完整性保持不变。 例如,您的应用程序所依赖的文件/数据库可能会因终止其他进程而损坏。
您可以查看此答案,其中显示了如何将Thread.Interrupt
方法与CancellationToken
结合使用。 只有在等待 state 时调用Thread.Interrupt
才会中断线程,因此如果线程在紧密循环中旋转,则Interrupt
将不起作用。 此外,中断线程并不能保证与中断工作关联的托管/非托管资源将被清除。 不过,您可以尝试一下,看看它是否解决了问题,并自行判断是否可以信任它在生产环境中运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.