我在C#中有一个程序可以进行一些服务调用。 我需要在这个程序中添加一些代码,以便在我点击一个按钮(winform)时能够停止这些服务调用[例如,如果调用太长而且用户感到无聊]。
困难在于我无法修改进行调用的代码块。
为了做到这一点,我计划用Unity Framework做一些拦截。 我想在每次输入服务调用代码块时创建一个Task。然后,如果用户单击我的按钮,则取消此任务。
我看过CancellationToken,但问题是我无法修改来电块,因此我无法if(ct.IsCancellationRequested)
或ct.ThrowIfCancellationRequested();
同样适用于AutoResetEvent& ManualResetEvent的。
调用并不总是异步的,并且使用了cancelToken,因此我认为捕捉OperationCanceledException
是不可能的。
我也看过使用Threads并做了一些Thread.Abort()
,但这种方法似乎每次有人都会杀死小狗。
以下是我当前程序的示例(拦截尚未实现,我想先在一次调用中测试它):
private void Test()
{
Task.Factory.StartNew(MyServiceCallFunction); // How to cancel the task when I press a button ?
}
// Can't touch the inside of this function :
private void MyServiceCallFunction()
{
// Blabla I prepare the datas for the call
// Blabla I do the call
}
我该怎么做? (我没有义务使用任务)
谢谢,
答案 0 :(得分:2)
"正确"这样做的方法是使用CancellationTokens,但由于你无法修改正在运行的代码,唯一的另一种方法是杀死小狗并使用Thread.Abort()
类似的东西:
Thread t;
Task.Factory.StartNew(() =>
{
t = Thread.CurrentThread;
MyServiceCallFunction();
});
t.Abort();
答案 1 :(得分:-1)
非常有趣的问题。当第三方通话正在进行TPL时,你当然无能为力;在你的情况下,它是MyServiceCallFunction()。
我一直处于类似的情况,这篇博文对我有帮助:https://social.msdn.microsoft.com/Forums/vstudio/en-US/d0bcb415-fb1e-42e4-90f8-c43a088537fb/aborting-a-long-running-task-in-tpl?forum=parallelextensions
(阅读:Stephen Toub - MSFTMicrosoft(MSFT)评论)
他提到了这个解决方案:
int Test(CancellationToken token)
{
Thread currentThread = Thread.CurrentThread;
using (token.Register(currentThread.Abort))
{
MyServiceCallFunction()
}
}
还用Task.Run(...)替换Task.Factory.StartNew(...);同样,感染后者更强,但更易读。