以正常方式在 C# 中创建后台线程 -
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 调用来获取线程句柄,还是有更简单的方法?
最佳答案
你可以这样做,但强烈不推荐。
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);
}
}
关于c# - 如何获取线程句柄以传递给 CancelSynchronousIO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24540131/