2009-09-26 45 views
2

我目前正在调查Thread.Interrupt如何与P/Invoke或本地调用一起播放。我已经阅读MSDN,它是不可能放弃(Thread.Abort)在本地调用的线程(其他用例也可能适用)。但是我没有找到任何对WaitSleepJoin状态的本地线程表示相同的引用。中断原生线程

这个问题不是关于是否应该调用Abort或Interrupt,而是关于在哪里可以找到关于此的授权文档。为此,G-ing没有提供任何有用的输出。

我测试的例子:

#ifdef NATIVEFUNCTIONS_EXPORTS 
#define NATIVEFUNCTIONS_API __declspec(dllexport) 
#else 
#define NATIVEFUNCTIONS_API __declspec(dllimport) 
#endif 

#include <iostream> 

extern "C" 
{ 
    NATIVEFUNCTIONS_API void EndlessWait(char const* mutexName) 
    { 
    std::cout << "entering the endless wait." << std::endl; 

    HANDLE mutex = CreateMutex(NULL, FALSE, mutexName); 
    WaitForSingleObject(mutex, INFINITE); 

    std::cout << "leaving the endless wait." << std::endl; 
    } 

}; 

本地C++ - DLL其中出口的函数,即无休止地等待一个互斥体。

现在C#.NET版本,它试图取消等待:

using System; 
using System.Threading; 
using System.Runtime.InteropServices; 

namespace InterruptingNativeWaitingThread 
{ 
    class Program 
    { 
    [DllImport("NativeFunctions.dll", CharSet=CharSet.Ansi)] 
    static extern void EndlessWait(string str); 

    static void Main(string[] args) 
    { 
     string mutexName = "interprocess_mutex"; 
     Mutex m = new Mutex(false, mutexName); 
     m.WaitOne(); 
     Thread t = new Thread(() => { EndlessWait(mutexName); }); 
     t.Start(); 
     Thread.Sleep(1000); 

     t.Abort(); 
     if(!t.Join(5000)) 
     Console.WriteLine("Unable to terminate native thread."); 

     t.Interrupt(); 
     if(!t.Join(5000)) 
     Console.WriteLine("Unable to interrupt the native wait."); 

     Console.WriteLine("Release the mutex."); 
     m.ReleaseMutex(); 
     t.Join(); 
    } 
    } 
} 

执行这个程序产生下面的输出:

entering the endless wait. 
Unable to terminate native thread. 
Unable to interrupt the native wait. 
Release the mutex. 
leaving the endless wait. 

预期中止不会在这方面的工作,但msdn并没有对中断说一句话。我期望它一方面能够工作:因为处于Wait状态的托管线程也会调用本地WaitForSingleObject或WaitForMultipleObjects;另一方面,被中断的本地线程有可能不支持期望异常,比什么都更好?

任何文档非常欢迎!

非常感谢,
Ovanes

附:我还在MSDN中发现中止等待,直到要中止的线程从非托管代码返回并且首先调用中断,如果线程处于WaitSleepJoin状态并且中止它。但这并不意味着中断不能中断原生的WaitSleepJoin。

回答

2

我怀疑线程处于WaitSleepJoin状态;记录中断只会中断此状态下的线程。查看线程的ThreadState属性以验证它处于什么状态。

+0

的确,线程处于运行状态。看起来像.NET拥有自己的线程状态管理。在调用t.Abort()之后,线程处于AbortRequested状态,但Thread.Interrupt不会中断它,因为它从不处于WaitSleepJoin状态。非常感谢! – ovanes 2009-09-26 19:15:14