2009-09-26 52 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