2012-10-27 72 views
5

GetCurrentThreadId()已被棄用,並且MSDN狀態ManagedThreadId替換它。替換AppDomain.GetCurrentThreadId();與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。

如何在不使用棄用方法的情況下使用此工作?原始堆棧 溢出文章聲明使用P/Invoke,但我不知道如何,這不是MSDN所說的。

回答

14

不,ManagedThreadId與操作系統的線程ID完全沒有任何關係。 CLR只是從1開始對線程進行編號。這是SQL Server組中一個嘗試使用光纖模擬.NET線程的項目的一個相當不幸的副作用。該項目被放棄,他們無法保持足夠穩定。令人遺憾的是,線程標識映射仍然是.NET 2.0發佈時的樣子。從技術上講,該功能仍然可用於自定義CLR主機以他們想要的方式實現線程,我不知道任何實際執行的主流實現。 SQL Server組故障是一個巨大的紅旗。

繞過廢棄警告的唯一方法是捏住GetCurrentThreadId()。該鏈接會讓您做出正確的拼寫聲明。

+0

出於好奇,我認爲kernell32.dll調用不會在單聲道下工作? – IamIC

+2

「#pragma警告禁用0618」在您使用GetCurrentThreadId源文件將壓制警告。 – Neutrino

+1

關於Neutrino的評論,禁用[警告CS0618](http://msdn.microsoft.com/en-us/library/x5ye6x1e.aspx)將禁用該文件中的所有Obsolete警告。這可以通過將目標代碼包裝在'#pragma warning disable 0618'中進行本地化......您的代碼在這裏......'#pragma warning restore 0618'。 ['#pragma warning'參考這裏](http://msdn.microsoft.com/en-us/library/441722ys.aspx) – cod3monk3y