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);
}
Run Code Online (Sandbox Code Playgroud)
我可以看到问题是获取线程的进程ID,而另一个获取应用程序的进程ID.
如何在不使用弃用方法的情况下使其工作?最初的Stack Overflow文章声明使用P/Invoke,但我不知道怎么做,这不是MSDN所说的.
Han*_*ant 14
不,ManagedThreadId与操作系统的线程ID完全没有关系.CLR只是对线程进行编号,从1开始.这是SQL Server组中一个项目试图用光纤模拟.NET线程的相当悲惨的副作用.该项目被放弃了,他们无法保持稳定.遗憾的是,线程ID映射与.NET 2.0发布时的方式不同.从技术上讲,该功能仍然可用于自定义CLR主机以他们想要的方式实现线程,我不知道任何主流实现实际上这样做.SQL Server组失败是一个巨大的红旗.
绕过废弃警告的唯一方法是使用GetCurrentThreadId().该链接将带您进行正确的pinvoke声明.