c# - 如何获取线程句柄以传递给 CancelSynchronousIO?

标签 c# multithreading

以正常方式在 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/

相关文章:

c# - double 格式 - 显示零位或两位小数

c++ - 在 QT 中从另一个 GUI 线程调用线程时出现问题

c# - 为什么我的 WCF 服务一次只处理 3 个并行请求?

c# - 应用程序无缘无故卡住,没有死锁,无法附加到 Visual Studio 进行调试

java - 在 AppEngine 上使用 Java Executor 导致 AccessControlException

c# - 如何确定.net 中的sql server 安全模式?

c# - 使用 C# 填写 HTML 表单

c# - 需要正则表达式来关闭或替换引号

c# - 带有两个小数点的字符串的 Double.TryParse

python - 如何使用 cmd2 和 wxPython 创建非阻塞 GUI?