2014-07-02 34 views
6

以正常的方式創建在C#後臺線程 -如何讓線程句柄傳遞給CancelSynchronousIO?

Thread t = new Thread(....); 
t.IsBackground = true; 
t.Start(); 
etc etc 

婉婷打電話CancelSynchronousIO從主線程取消在後臺線程阻塞IO調用。不知道如何讓一個線程處理中一個IntPtr的形式傳遞給函數:

[DllImport("kernel32.dll", SetLastError=true)] 
static extern bool CancelSynchronousIo(IntPtr threadHandle); 

似乎是得到一個線程ID的各種方式,但不是一個手柄?並且獲取線程ID的方式似乎只在託管環境中爲您提供了一個ID,因此不使用PInvoke調用?我猜我錯過了一些東西。

我需要做其他的PInvoke調用來獲得線程句柄還是有更簡單的方法?

+0

您的代碼可能在託管線程上運行,而不是本機線程。 –

+0

請參閱:http://msdn.microsoft.com/en-us/library/74169f59(v=vs.110).aspx –

+1

@ DanielA.White:託管線程_are_本機線程;纖維幾乎從不使用。 – SLaks

回答

3

你可以這樣做,但極不推薦。

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

class Program 
{ 
    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern uint GetCurrentThreadId(); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern IntPtr OpenThread(uint desiredAccess, bool inheritHandle, uint threadId); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern bool CloseHandle(IntPtr handle); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    static extern bool CancelSynchronousIo(IntPtr threadHandle); 

    static bool CancelSynchronousIo(uint threadId) 
    { 
     // GENERIC_WRITE, Non-inheritable 
     var threadHandle = OpenThread(0x40000000, false, (uint)threadId); 
     var ret = CancelSynchronousIo(threadHandle); 

     CloseHandle(threadHandle); 

     return ret; 
    } 

    static void Main(string[] args) 
    { 
     uint threadId = 0; 

     using (var threadStarted = new AutoResetEvent(false)) 
     { 
      var thread = new Thread(() => 
      { 
       try 
       { 
        Thread.BeginThreadAffinity(); 
        threadId = GetCurrentThreadId(); 

        threadStarted.Set(); 

        // will throws System.OperationCanceledException 
        Console.ReadLine(); 
       } 
       finally 
       { 
        Thread.EndThreadAffinity(); 
       } 
      }); 

      thread.Start(); 

      threadStarted.WaitOne(); 
     } 

     Debugger.Break(); 

     CancelSynchronousIo(threadId); 
    } 
} 
+0

你能解釋或引用爲什麼不推薦? – jklemmack