替换AppDomain.GetCurrentThreadId();与ManagedThreadId [英] Replacing AppDomain.GetCurrentThreadId(); with ManagedThreadId

查看:733
本文介绍了替换AppDomain.GetCurrentThreadId();与ManagedThreadId的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GetCurrentThreadId()已被弃用,并且MSDN声明ManagedThreadId替换了它.

GetCurrentThreadId() has been deprecated, and MSDN states ManagedThreadId replaces it.

但是,我得到了不同的结果,后者导致我的代码中出现异常.我的代码改编自这篇文章.

However, I'm getting different results, and the latter causes an exception in my code. My code is adapted from this post.

        public static void SetThreadProcessorAffinity(params byte[] cpus)
        {
            if (cpus == null)
            {
                throw new ArgumentNullException("cpus");
            }

            if (cpus.Length == 0)
            {
                throw new ArgumentException(@"You must specify at least one CPU.", "cpus");
            }

            // Supports up to 64 processors
            long cpuMask = 0;
            byte max = (byte)Math.Min(Environment.ProcessorCount, 64);

            foreach (byte cpu in cpus)
            {
                if (cpu >= max)
                {
                    throw new ArgumentException(@"Invalid CPU number.");
                }

                cpuMask |= 1L << cpu;
            }

            // Ensure managed thread is linked to OS thread; does nothing on default host in current .NET versions
            Thread.BeginThreadAffinity();

#pragma warning disable 618
            // The call to BeginThreadAffinity guarantees stable results for GetCurrentThreadId,
            // so we ignore the obsolete warning.
            int osThreadId = AppDomain.GetCurrentThreadId();
            osThreadId = Thread.CurrentThread.ManagedThreadId;// NOT THE SAME VALUE
#pragma warning restore 618

            // Find the ProcessThread for this thread
            ProcessThread thread = Process.GetCurrentProcess().Threads.Cast<ProcessThread>()
                .Where(t => t.Id == osThreadId).Single();

            // Set the thread's processor affinity
            thread.ProcessorAffinity = new IntPtr(cpuMask);
        }

我可以看到问题是一个获取线程的进程ID,而另一个获取应用程序的进程ID.

I can see the issue is one gets the thread's process ID while the other gets the app's process ID.

如何在不使用不推荐使用的方法的情况下使它正常工作?原始的堆栈溢出"文章指出要使用 P/调用,但我不知道如何,这不是MSDN规定的.

How do I get this to work without using the deprecated method? The original Stack Overflow article states to use P/Invoke, but I don't know how, and that isn't what MSDN states.

推荐答案

否,ManagedThreadId与操作系统的线程ID完全没有关系. CLR简单地从1开始对线程进行编号.这是SQL Server组中试图用光纤模拟.NET线程的项目的一个相当悲惨的副作用.该项目被放弃了,他们无法使其足够稳定.不幸的是,线程ID映射保留了.NET 2.0发行时的方式.从技术上讲,该功能仍可用于自定义CLR主机,以其所需的方式实现线程,我不知道实际上有任何主流的实现方式. SQL Server组失败是一个巨大的危险信号.

No, ManagedThreadId has no relationship at all with the operating system's thread ID. The CLR simply numbers threads, starting at 1. This is a fairly tragic side-effect of a project in the SQL Server group that tried to emulate .NET threads with fibers. The project was abandoned, they could not get it stable enough. Sadly the thread ID mapping was left the way it was when .NET 2.0 shipped. Technically the feature is still available for custom CLR hosts to implement threads the way they want, I'm not aware of any mainstream implementation actually doing so. The SQL Server group failure is a giant red flag.

绕过过时警告的唯一方法是将 GetCurrentThreadId()固定.该链接将带您进行正确的拼音声明.

The only way to bypass the obsoletion warning is to pinvoke GetCurrentThreadId(). The link takes you to do correct pinvoke declaration.

这篇关于替换AppDomain.GetCurrentThreadId();与ManagedThreadId的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆