Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将单个同步操作与带有CancellationToken的任务包装在一起?_C#_.net_Async Await - Fatal编程技术网

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终止一个进程是否会确保所有资源(从新进程中启动)都被实际释放?