Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在没有AppDomain.GetCurrentThreadId()的情况下获取当前线程id,以便它实际工作?_C#_Multithreading_Atomic_Appdomain - Fatal编程技术网

C# 如何在没有AppDomain.GetCurrentThreadId()的情况下获取当前线程id,以便它实际工作?

C# 如何在没有AppDomain.GetCurrentThreadId()的情况下获取当前线程id,以便它实际工作?,c#,multithreading,atomic,appdomain,C#,Multithreading,Atomic,Appdomain,因为AppDomin.GetCurrentThreadId()已过时 “AppDomain.GetCurrentThreadId已被弃用,因为它没有 当托管线程在光纤上运行时,提供稳定的Id(也称为 轻量级线程)。要获取托管线程的稳定标识符, 在线程上使用ManagedThreadId属性。 " 我尽量不使用它。然而,“Thread.CurrentThread.ManagedThreadId”可以工作的解释是毫无价值的,因为它没有提供Win32线程id,而我需要它来进行Win32调用。所以我自己

因为AppDomin.GetCurrentThreadId()已过时

“AppDomain.GetCurrentThreadId已被弃用,因为它没有 当托管线程在光纤上运行时,提供稳定的Id(也称为 轻量级线程)。要获取托管线程的稳定标识符, 在线程上使用ManagedThreadId属性。 "

我尽量不使用它。然而,“Thread.CurrentThread.ManagedThreadId”可以工作的解释是毫无价值的,因为它没有提供Win32线程id,而我需要它来进行Win32调用。所以我自己实现了它,如下所示

public sealed class AppDomainExtender
{
    public static int GetCurrentThreadId_New()
    {
        return Process.GetCurrentProcess().Threads.OfType<ProcessThread>().SingleOrDefault(x => x.ThreadState == System.Diagnostics.ThreadState.Running).Id;
    }
}
公共密封类AppDomainExtender
{
公共静态int GetCurrentThreadId_New()
{
返回Process.GetCurrentProcess().Threads.OfType().SingleOrDefault(x=>x.ThreadState==System.Diagnostics.ThreadState.Running).Id;
}
}
现在有两个问题

  • 如果它可以工作,那么它的功能是否与AppDomain.GetCurrentThreadId完全相同
  • 它不起作用,因为在SingleOrDefault循环中运行的线程可能会发生变化。这种行为很奇怪,但它给了我一个invalidoOperationException(“序列包含多个元素”)。例如,在使用多个桌面时(我假设只有将执行循环的线程复制到另一个id时,才可能发生这种情况)
问题:

  • AppDomain.GetCurrentThreadId是否被错误声明为已过时
  • 如何使语句“Process.GetCurrentProcess().Threads.OfType().SingleOrDefault(x=>x.ThreadState==System.Diagnostics.ThreadState.Running).Id”成为原子的,或者甚至是可能的

  • AppDomain.GetCurrentThreadId()的弃用是一个不方便的事实,当然不是一个“错误”的声明。从.NET 2.0开始,.NET线程和操作系统线程之间的关联被破坏。自定义CLR主机可以通过实现。或者换句话说,您不能保证两个不同的.NET线程使用具有不同线程ID的不同操作系统线程

    在20世纪90年代和21世纪初,这通常是一种流行的做法,被称为“轻量级线程”、协例程、光纤、“绿色线程”等。其想法是避免操作系统进行线程上下文切换,而是在软件中对CPU寄存器进行上下文切换。SQL Server是此功能的主要受益者,它内置了对“光纤模式”的支持

    虽然SQL Server团队获得了该功能,但他们最终决定不发布该功能。当他们无法使项目足够稳定时,他们放弃了该项目。一个可能是激发灵感的问题,在他们的项目到期的同一年发表。没有再次尝试此操作。一点也不,因为该功能已被多核革命淘汰。现代内核中上下文切换的成本主要取决于CPU缓存的状态,不可能与每个拥有自己的一级和二级缓存的内核竞争

    我不知道有任何CLR主机实际实现了IClrTask,SQL Server团队的失败无疑是一个巨大的危险信号。但是,这并不排除这种可能性,您可能需要担心的场景是在支持托管语言脚本的大型非托管应用程序的上下文中运行代码。CAD程序就是一个典型的例子


    如果你的代码在这种情况下实际运行,那么你可能会死在水里,所以把你的激光设置为眩晕并继续前进。除了不得不忍受过时警告之外,最明智的解决办法是使用pinvoke。它非常快。

    您是否尝试PInvoke GetCurrentThreadId()方法?我正在Windows 7上实现一个基于屏幕截图的多桌面ui自动化应用程序,user32.dll、gdi32.dll和kernel32.dll有如此多的基本用法,不能忽略。PIvoked'GetCurrentThreadId()'与'AppDomain.GetCurrentThreadId()'的功能是否完全相同?非常有趣,谢谢!尽管在我看来.Net“纤维”实际上不是线程,因此“GetCurrentThreadId()”不应该被标记为过时。此外,这些“纤维”不应该被称为线程,它们的行为就像协程一样。这只是一种观点,不会改变事实。事实上,CLR团队曾希望支持NT Fibers for 2.0,但最终未能实现,请参见Duffy在Windows p449上的并发编程。