WPF应用程序退出暂停工作线程

时间:2016-09-28 19:32:30

标签: c# wpf multithreading deadlock dispatcher

考虑以下情况:

我在本机API(P / Invoke)的顶部创建了一个托管包装。
该API运行USB设备,在专用线程上执行I / O操作。 此外,此API是单线程的,因此调用其方法并最终确定它必须在已初始化它的同一线程上完成。
它的要点是:

//Runs in the context of a new System.Threading.Thread instance
void Loopback()
{
 InitializeAPI();
 try
 {

 while(_work)
 {
  //Poll API
 }
 }
 finally
 {
  FinalizeAPI()
  //Unblock disposing thread
 }
}

void Dispose()
{
  _work=false;
  //Block untill Loopback method returns
}

在WPF应用程序的上下文中使用上述包装器时,我在Application.OnExit覆盖中调用我的包装器类的Dispose方法。这会导致死锁。

单击VS中的Thread窗口,可以清楚地看到专用于本机API的工作线程停留在与当前WPF Dispatcher关联的某个等待句柄上。我想这是有道理的,因为WPF希望在最终确定时暂停所有内容。

另一方面,

我的Dispose方法 - 在设备的API完成之前不得返回,所以当专用线程完成时,我连接了一个TaskCompletionSource来完成它的任务。

我的Dispose方法的作用是通过切换循环条件变量并立即阻止TaskCompletionSource的任务来启动线程的结束。

专用线程永远不会完成,因为它被WPF阻止,并且UI线程永远不会完成,因为它阻塞了永远不会完成的任务,因此死锁。

有没有办法克服这个问题,同时保持与包装器端的客户端框架无关?

非常感谢帮助!

0 个答案:

没有答案