为什么Thread.Join()挂起,即使线程中的方法已经返回?

时间:2011-11-25 08:44:38

标签: c# wpf multithreading

我有一个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对象。但是这些细节据我所知与冻结无关,因为即使在简化代码中也会发生冻结。]

1 个答案:

答案 0 :(得分:7)

根据您的代码;它看起来好像你正确地做了,但线程永远不会真正终止。尝试在线程中的函数的END处设置断点;而不是return关键字(如果你在return语句中进行某种处理以阻止线程退出),如下图所示 enter image description here。使用authenticationThread.Name(或示例中所示的mthread.Name)命名线程也可以帮助调试。如果线程REALLY终止,你应该看到“线程'你的名字'(0x143c)退出了代码0(0x0)。”在Visual Studio的“输出”窗口中。