Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 当工作线程调用Dispatcher.Invoke()时,Thread.Abort()会创建死锁_C#_Multithreading_Deadlock - Fatal编程技术网

C# 当工作线程调用Dispatcher.Invoke()时,Thread.Abort()会创建死锁

C# 当工作线程调用Dispatcher.Invoke()时,Thread.Abort()会创建死锁,c#,multithreading,deadlock,C#,Multithreading,Deadlock,两个线程:主线程(GUI)和辅助线程。工作进程要求主进程使用Dispatcher.Invoke(…)进行更新。在某些时候,由于用户的干预,我必须使用Thread1.abort()中止工作进程。但僵局似乎是按以下顺序产生的: T1调用一个动作 主线程中止T1 我知道,Aborting是邪恶的(我应该怎么做?每隔两行插入checkifcancelled()),但假设这是必要的-我如何防止死锁?在Windows线程模型中,不能从线程执行上下文之外中止线程。您应该向工作线程发出退出其工作线程方法的信号

两个线程:主线程(GUI)和辅助线程。工作进程要求主进程使用
Dispatcher.Invoke(…)
进行更新。在某些时候,由于用户的干预,我必须使用
Thread1.abort()
中止工作进程。但僵局似乎是按以下顺序产生的:

  • T1调用一个动作
  • 主线程中止T1

  • 我知道,
    Abort
    ing是邪恶的(我应该怎么做?每隔两行插入
    checkifcancelled()
    ),但假设这是必要的-我如何防止死锁?

    在Windows线程模型中,不能从线程执行上下文之外中止线程。您应该向工作线程发出退出其工作线程方法的信号(然后终止线程),要实现这一点,您可以使用CancellationToken或其他跨线程标志。Thread.Abort()将抛出异常,但实际上并不能保证在将其与锁定多线程算法一起使用时有足够的时间来执行此操作


    最好的替代方法是使用
    BeginInvoke()
    调用,然后使用
    WaitHandle
    等待答案(这将暂停线程,而不会花费CPU周期等待循环)。当主线程参与调用请求时,它将通过
    WaitHandle
    发出信号,表示线程可以继续。使用标志指示线程是否必须在恢复时退出。

    使用Dispatcher.Invoke()而不是Dispatcher.BeginInvoke()的意义在于可以使用其返回值。您可以抛出一个异常并在线程中捕获它。这为您提供了两种非常好的方法来停止线程而不必中止它。您真的需要立即中止线程吗?你不能在线程的主循环中检查一次(或几次)IsCancellationRequested吗?@HansPassant,我不明白你的意思。我怎样才能用那种方式停止线程?我有一个长期运行的工作线程,它不时地请求GUI调用,这对我有什么帮助?这似乎没有任何作用,提到Dispatcher.Invoke()似乎是多余的。改为使用任务类。它支持使用CancellationToken进行取消,从而避免了死锁倾向中止()的需要。并允许您在UI线程上运行代码,而无需使用Dispatcher、TaskScheduler.FromCurrentSynchronizationContext.Calling
    thread.Abort
    就像是通过射击驾驶员的头部来停车。汽车会停下来,但不知道在这个过程中会造成什么损害。