C# 如何将单个同步操作与带有CancellationToken的任务包装在一起?
我有一个单一的同步操作,可能需要很多时间才能完成。操作的调用者提供了一个C# 如何将单个同步操作与带有CancellationToken的任务包装在一起?,c#,.net,async-await,C#,.net,Async Await,我有一个单一的同步操作,可能需要很多时间才能完成。操作的调用者提供了一个CancellationToken,当令牌被取消时,操作应该立即停止(在这种情况下,取消后几毫秒内也可以工作) 如何使用CancellationToken将其包装到任务中 我无法更改呼叫代码,也无法更改呼叫本身 过去是什么:LongOperation() 我现在拥有的:await Task.Run(()=>LongOperation(),cancellationToken) 显然,这不起作用,因为您必须轮询指定给任务的操作内
CancellationToken
,当令牌被取消时,操作应该立即停止(在这种情况下,取消后几毫秒内也可以工作)
如何使用CancellationToken将其包装到任务中
我无法更改呼叫代码,也无法更改呼叫本身
过去是什么:LongOperation()代码>
我现在拥有的:await Task.Run(()=>LongOperation(),cancellationToken)代码>
显然,这不起作用,因为您必须轮询指定给任务的操作内的令牌。运行
我无法更改呼叫代码,也无法更改呼叫本身
显然,这不起作用,因为您必须轮询Task.Run操作中的令牌
到目前为止,最简单的解决方案是取消其中一项要求:要么允许忽略CancellationToken
,要么更改调用的代码
如果这真的、真的、诚实地不可能,那么您需要在另一个进程中运行代码。因此,您需要启动一个可以访问该方法的子进程,将所有参数封送到它,然后封送回任何结果值或异常。然后,当令牌被取消时,终止进程
做同样的事情有一些不太安全的方法:您可以在另一个AppDomain
中运行代码并在取消时关闭AppDomain
,或者您可以在另一个线程中运行代码并在取消时中止线程。但这两种情况都很容易导致资源泄漏或应用程序稳定性问题。唯一真正安全的方法是单独处理。您尝试过什么?正如您所发现的,您必须在您所说的无法修改的代码中执行此操作。在代码不知道的情况下任意中止执行很容易导致某些资源处于无效/损坏状态。看,你做不到。您的同步方法需要接受CancallationToken,并且您需要定期检查您是否应该中断对该令牌信号的执行。如果您无法更改同步方法,async/await将不会帮助您。您可以创建一个新线程,执行该线程并按需使用中止。对于OP,也不要因为启动并将参数发送到单独的进程而感到害怕。我不得不做一些类似的事情,使整个过程相对轻松。@ScottChamberlain:说得好!上一次我不得不这么做的时候,WCF还不存在(也不存在.NET),所以它是直接向上的stdin/stdout/stderr重定向-使用多个线程来防止死锁。丑!在长时间运行的同步方法调用期间终止进程也可能不是最好的主意。我闻到内存泄漏的味道。@Botonomous:这是不可能的-从操作系统的角度来看,这个过程是资源使用的范围。如果终止一个进程,它的所有内存都将被回收。@StephenCleary终止一个进程是否会确保所有资源(从新进程中启动)都被实际释放?