以正常方式在C#中创建后台线程 -
Thread t = new Thread(....);
t.IsBackground = true;
t.Start();
etc etc
Run Code Online (Sandbox Code Playgroud)
想要CancelSynchronousIO从主线程调用取消后台线程上的阻塞IO调用.不知道如何以IntPtr的形式获取线程句柄以传递给函数:
[DllImport("kernel32.dll", SetLastError=true)]
static extern bool CancelSynchronousIo(IntPtr threadHandle);
Run Code Online (Sandbox Code Playgroud)
似乎有各种方法来获取线程ID,但不是句柄?获取线程ID的方式似乎只在托管环境中提供了一个ID,所以没有用于PInvoke调用?我猜我错过了什么.
我是否需要执行其他PInvoke调用以获取线程句柄或者是否有更简单的方法?
小智 6
您可以这样做,但强烈不建议这样做。
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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2210 次 |
| 最近记录: |