6

GetCurrentThreadId()は非推奨になり、MSDNはManagedThreadIdがそれを置き換えると述べています。

ただし、異なる結果が得られ、後者の場合、コードで例外が発生します。私のコードはこの投稿から採用されています。

        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を取得することです。

非推奨のメソッドを使用せずにこれを機能させるにはどうすればよいですか?元のStackOverflowの記事では、P / Invokeを使用するように述べられていますが、その方法がわかりません。MSDNが述べていることではありません。

4

1 に答える 1

16

いいえ、ManagedThreadId はオペレーティング システムのスレッド ID とはまったく関係がありません。CLR は、1 から始まるスレッドに番号を付けるだけです。これは、ファイバーを使用して .NET スレッドをエミュレートしようとした SQL Server グループのプロジェクトのかなり悲惨な副作用です。プロジェクトは放棄され、十分に安定させることができませんでした。残念ながら、スレッド ID のマッピングは、.NET 2.0 が出荷されたときのまま残されていました。技術的には、カスタム CLR ホストがスレッドを好きなように実装するためにこの機能を引き続き利用できますが、実際にそうしている主流の実装については知りません。SQL Server グループの障害は、大きな危険信号です。

廃止の警告を回避する唯一の方法は、 GetCurrentThreadId()を pinvoke することです。リンクは、正しい pinvoke 宣言を行うためにあなたを連れて行きます。

于 2012-10-27T13:44:29.783 に答える