我有一个WPF应用程序,它使用一些库代码进行身份验证,需要在单线程单元线程中运行。我的方法是生成一个单独的线程来获取身份验证对象,阻塞直到线程返回然后继续执行。但是,在一些实例中,我的应用程序挂起在Thread.Join()上,即使线程方法已经返回。
public static ClaimsAuthenticationResult GetClientContextAndCookieCollection(string siteUrl, out CookieCollection cookieResult)
{
ClaimsAuthenticationResult authResult = new ClaimsAuthenticationResult();
// Authentication module needs to run in single-thread apartment state because it uses
// COM library calls where this is required
Thread authenticationThread = new Thread(new ThreadStart(threadMethod));
authenticationThread.SetApartmentState(ApartmentState.STA);
authenticationThread.Start();
// Block until thread completion
authenticationThread.Join(); // Application hangs here
return authResult;
}
private static void threadMethod() {
// In proper application: set result. But for debugging, return immediately
return;
}
我是mulththreading和WPF的新手,所以我可能会做一些愚蠢的事情。有谁看到这里发生了什么?为了记录,如果我没有将线程设置为STA,我不会遇到问题,但这是一个要求。
[编辑:看起来错误只发生在我通过WPF视图中的验证绑定调用指定的方法时,特别是在TextBox上。当我在视图的构造函数中调用相同的代码时,代码按预期运行。这将是一个可行的解决方法,但了解这里实际发生的事情会很有趣。]
[编辑:此处的代码已经简化了一些调试 - 在生产代码中,线程方法位于AuthThreadWorker对象中,该对象允许将身份验证过程的结果返回给authResult对象。但是这些细节据我所知与冻结无关,因为即使在简化代码中也会发生冻结。]
答案 0 :(得分:7)
根据您的代码;它看起来好像你正确地做了,但线程永远不会真正终止。尝试在线程中的函数的END处设置断点;而不是return关键字(如果你在return语句中进行某种处理以阻止线程退出),如下图所示 。使用authenticationThread.Name(或示例中所示的mthread.Name)命名线程也可以帮助调试。如果线程REALLY终止,你应该看到“线程'你的名字'(0x143c)退出了代码0(0x0)。”在Visual Studio的“输出”窗口中。