如何中止CCR线程\任务?

时间:2021-05-29 18:14:13

I want to implement a timeout on the execution of tasks in a project that uses the CCR. Basically when I post an item to a Port or enqueue a Task to a DispatcherQueue I want to be able to abort the task or the thread that its running on if it takes longer than some configured time. How can I do this?

我想在使用CCR的项目中执行任务的超时。基本上,当我将项目发布到端口或将任务排入DispatcherQueue时,我希望能够中止任务或其运行的线程(如果花费的时间超过某个配置的时间)。我怎样才能做到这一点?

2 个解决方案

#1


Can you confirm what you are asking? Are you running a long-lived task in the Dispatcher? Killing the thread would break the CCR model, so you need to be able to signal to the thread to finish its work and yield. Assuming it's a loop that is not finishing quick enough, you might choose to enqueue a timer:

你能证实你在问什么吗?你在Dispatcher中运行一个长期存在的任务吗?杀死线程会破坏CCR模型,因此您需要能够向线程发出信号以完成其工作和产量。假设它是一个没有足够快速完成的循环,您可以选择将计时器排入队列:

var resultTimeoutPort = new Port<DateTime>();
dispatcherQueue.EnqueueTimer(TimeSpan.FromSeconds(RESULT_TIMEOUT), 
                             resultTimeoutPort);

and ensure the blocking thread has available a reference to resultTimeoutPort. In the blocking loop, one of the exit conditions might be:

并确保阻塞线程可用对resultTimeoutPort的引用。在阻塞循环中,其中一个退出条件可能是:

do
{
    //foomungus amount of work
}while(resultTimeoutPort.Test()==null&&
       someOtherCondition)

Please post more info if I'm barking up the wrong tree.

如果我正在咆哮错误的树,请发布更多信息。

#2


You could register the thread (Thread.CurrentThread) at the beginning of your CCR "Receive" handler (or in a method that calls your method via a delegate). Then you can do your periodic check and abort if necessary basically the same way you would have done it if you created the thread manually. The catch is that if you use your own Microsoft.Ccr.Core.Dispatcher with a fixed number of threads, I don't think there is a way to get those threads back once you abort them (based on my testing). So, if your dispatcher has 5 threads, you'll only be able to abort 5 times before posting will no longer work regardless of what tasks have been registered. However, if you construct a DispatcherQueue using the CLR thread pool, any CCR threads you abort will be replaced automatically and you won't have that problem. From what I've seen, although the CCR dispatcher is recommended, I think using the CLR thread pool is the way to go in this situation.

您可以在CCR“Receive”处理程序的开头(或通过委托调用方法的方法)中注册线程(Thread.CurrentThread)。然后,您可以进行定期检查并在必要时中止,基本上与手动创建线程时相同。问题是,如果您使用自己的Microsoft.Ccr.Core.Dispatcher具有固定数量的线程,我不认为有一种方法可以在中止它们后恢复这些线程(基于我的测试)。因此,如果您的调度员有5个线程,那么无论注册了什么任务,您都只能在发布之前中止5次,然后才能继续工作。但是,如果使用CLR线程池构造DispatcherQueue,则中止的任何CCR线程都将自动替换,您将不会遇到此问题。从我所看到的,虽然推荐使用CCR调度程序,但我认为使用CLR线程池是这种情况下的方法。

#1


Can you confirm what you are asking? Are you running a long-lived task in the Dispatcher? Killing the thread would break the CCR model, so you need to be able to signal to the thread to finish its work and yield. Assuming it's a loop that is not finishing quick enough, you might choose to enqueue a timer:

你能证实你在问什么吗?你在Dispatcher中运行一个长期存在的任务吗?杀死线程会破坏CCR模型,因此您需要能够向线程发出信号以完成其工作和产量。假设它是一个没有足够快速完成的循环,您可以选择将计时器排入队列:

var resultTimeoutPort = new Port<DateTime>();
dispatcherQueue.EnqueueTimer(TimeSpan.FromSeconds(RESULT_TIMEOUT), 
                             resultTimeoutPort);

and ensure the blocking thread has available a reference to resultTimeoutPort. In the blocking loop, one of the exit conditions might be:

并确保阻塞线程可用对resultTimeoutPort的引用。在阻塞循环中,其中一个退出条件可能是:

do
{
    //foomungus amount of work
}while(resultTimeoutPort.Test()==null&&
       someOtherCondition)

Please post more info if I'm barking up the wrong tree.

如果我正在咆哮错误的树,请发布更多信息。

#2


You could register the thread (Thread.CurrentThread) at the beginning of your CCR "Receive" handler (or in a method that calls your method via a delegate). Then you can do your periodic check and abort if necessary basically the same way you would have done it if you created the thread manually. The catch is that if you use your own Microsoft.Ccr.Core.Dispatcher with a fixed number of threads, I don't think there is a way to get those threads back once you abort them (based on my testing). So, if your dispatcher has 5 threads, you'll only be able to abort 5 times before posting will no longer work regardless of what tasks have been registered. However, if you construct a DispatcherQueue using the CLR thread pool, any CCR threads you abort will be replaced automatically and you won't have that problem. From what I've seen, although the CCR dispatcher is recommended, I think using the CLR thread pool is the way to go in this situation.

您可以在CCR“Receive”处理程序的开头(或通过委托调用方法的方法)中注册线程(Thread.CurrentThread)。然后,您可以进行定期检查并在必要时中止,基本上与手动创建线程时相同。问题是,如果您使用自己的Microsoft.Ccr.Core.Dispatcher具有固定数量的线程,我不认为有一种方法可以在中止它们后恢复这些线程(基于我的测试)。因此,如果您的调度员有5个线程,那么无论注册了什么任务,您都只能在发布之前中止5次,然后才能继续工作。但是,如果使用CLR线程池构造DispatcherQueue,则中止的任何CCR线程都将自动替换,您将不会遇到此问题。从我所看到的,虽然推荐使用CCR调度程序,但我认为使用CLR线程池是这种情况下的方法。