2012-10-27 14 views
5

GetCurrentThreadId()は非推奨となっており、MSDNではManagedThreadIdがそれを置き換えます。AppDomain.GetCurrentThreadId();を置き換えます。 with ManagedThreadId

しかし、私は別の結果を得ています。後者は私のコードで例外を引き起こします。私のコードは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を取得するという問題が発生しています。

廃止予定の方法を使用せずにこれを動作させるにはどうすればよいですか?元のStack  オーバーフロー記事の状態でP/Invokeを使用していますが、私はどのようにしているのかわかりませんが、それはMSDNの状態ではありません。

答えて

14

いいえ、ManagedThreadIdは、オペレーティングシステムのスレッドIDとはまったく関係がありません。 CLRはスレッド数を1から始めるだけです。これは、.NETスレッドをファイバでエミュレートしようとしたSQL Serverグループのプロジェクトのかなり悲劇的な副作用です。プロジェクトは放棄され、十分に安定していない。悲しいことに、スレッドIDのマッピングは、.NET 2.0が出荷されたときのように残っていました。技術的には、カスタムCLRホストが希望の方法でスレッドを実装できる機能はまだありますが、実際にそうしている主流の実装はわかりません。 SQL Serverグループの失敗は巨大な赤旗です。

obsoletion警告をバイパスする唯一の方法は、GetCurrentThreadId()をピンボケすることです。このリンクをクリックすると正しいpinvoke宣言ができます。

+0

好奇心の高まりから、私はkernell32.dll呼び出しがMonoではうまくいかないと思いますか? – IamIC

+2

GetCurrentThreadIdを使用するソースファイル内の "#pragma warning disable 0618"は警告を抑制します。 – Neutrino

+1

ニュートリノのコメントに関して、[警告CS0618](http://msdn.microsoft.com/en-us/library/x5ye6x1e.aspx)を無効にすると、そのファイルの廃止された警告がすべて無効になります。これは、ターゲットコードを '#pragma warning disable 0618' ...あなたのコードここに' #pragma warning restore 0618'でラップすることでローカライズできます。 ['#pragma warning'リファレンスはこちら](http://msdn.microsoft.com/en-us/library/441722ys.aspx) – cod3monk3y

関連する問題