C# 如何检查函数是否在特定线程上被调用?

C# 如何检查函数是否在特定线程上被调用?,c#,multithreading,C#,Multithreading,如果我有一个线程,它是主应用程序线程和一个辅助线程。如何检查线程B中是否调用了函数 基本上,我正在尝试实现以下代码snippit: public void ensureRunningOnCorrectThread() { if( function is being called within ThreadB ) { performIO() } else { // call performIO so that it is

如果我有一个线程,它是主应用程序线程和一个辅助线程。如何检查线程B中是否调用了函数

基本上,我正在尝试实现以下代码snippit:

public void ensureRunningOnCorrectThread()
{
    if( function is being called within ThreadB )
    {
         performIO()
    }
    else
    {
         // call performIO so that it is called (invoked?) on ThreadB
    }
}
有没有办法在C#中实现这一功能,或者有没有更好的方法来解决这个问题

编辑1

我注意到MSDN文档中有以下内容,尽管我怀疑这是否是一件好事!:

// if function is being called within ThreadB
if( System.Threading.Thread.CurrentThread.Equals(ThreadB) )
{

}
编辑2


我意识到我用错误的方式看待这个问题(感谢下面的答案帮助我看到了这一点),我所关心的是IO不会发生在ThreadA上。这意味着它可能发生在ThreadB或任何其他线程上,例如BackgroundWorker。我决定在上述f语句的else部分中创建一个新的BackgroundWorker,以确保IO以非阻塞方式执行。我不完全确定这是否是解决我问题的最佳方案,但它似乎有效

这里有一种方法:

if (System.Threading.Thread.CurrentThread.ManagedThreadId == ThreadB.ManagedThreadId) 
            ...
我对.NET的
线程
类实现了解不够,无法知道上面的比较是否等同于
Equals()
,但如果没有这些知识,比较ID是安全的

可能有更好(更好=更容易、更快等)的方法来完成您想要做的事情,这取决于以下几点:

  • 您正在构建什么样的应用程序(ASP.NET、WinForms、console等)
  • 为什么只在一个线程上强制执行I/O
  • 这是什么类型的I/O?(例如,写入一个文件?网络I/O受限于一个套接字?等)
  • 相对于锁定成本、并发工作线程数量等,您的性能限制是什么
  • 代码中的“else”子句是否需要阻塞、激发和遗忘,或者更复杂的东西
  • 如何处理超时、死锁等问题
将此信息添加到您的问题中会很有帮助,尽管如果您的问题是WinForms应用程序,并且您谈论的是面向用户的GUI I/O,您可以跳过其他问题,因为场景很明显

请记住,
//调用performIO,以便在ThreadB上调用(调用?)
实现将根据是WinForms、ASP.NET还是console等而有所不同

如果是WinForms,请查看处理它的酷方法。另请参阅MSDN,了解通常如何使用

如果控制台或通用服务器应用程序(无GUI),您需要了解如何让主线程知道它有工作等待-并且您可能想考虑一个替代的实现,它有一个I/O工作者线程或线程池,它只是围绕着执行排队的I/O请求来排队。或者,您可能需要考虑同步I/O请求(更容易),而不是将调用编组到一个线程(更硬)。


如果是ASP.NET,则可能是以错误的方式实现的。通常,使用ASP.NET异步页面和/或(如上)使用
lock{}
或其他同步方法将snchronizing同步到I/O更有效

代码段的另一部分,在ThreadB上调用PerformIO只有在ThreadB是运行Messageloop的主线程时才起作用


所以也许你应该重新考虑一下你在这里做什么,这不是一个正常的建筑

您尝试执行的操作与windows窗体控件的
invokererequired
属性的操作相反,因此,如果它是一个窗口窗体应用程序,您可以只使用主窗体的属性:

if (InvokeRequired) {
   // running in a separate thread
} else {
  // running in the main thread, so needs to send the task to the worker thread
}

除了
performIO()
函数之外,您的次线程还做了什么?如果不是,那么一个简单的方法就是使用一个。让次线程处于while循环中,等待事件被设置。当事件发出信号时,辅助线程可以执行I/O处理。要向事件发送信号,请让主线程调用事件对象的方法

using System.Threading;
static void Main(string[] args)
{
    ManualResetEvent processEvent = new ManualResetEvent(false);
    Thread thread = new Thread(delegate() {
        while (processEvent.WaitOne()) {
            performIO();
            processEvent.Reset(); // reset for next pass...
        }
    });
    thread.Name = "I/O Processing Thread"; // name the thread
    thread.Start();

    // Do GUI stuff...

    // When time to perform the IO processing, signal the event.
    processEvent.Set();
}

另外,请养成在创建任何System.Threading.Thread对象时命名它们的习惯。创建次线程时,通过属性设置线程名称。这将有助于您在调试会话中查看“线程”窗口,如果线程标识有疑问,还允许您将线程名称打印到控制台或输出窗口。

我认为仅比较ID比比较整个对象更有效!我也在研究如何强制在ThreadB而不是当前线程上调用performIO。有什么想法吗?看看我上面更新的答案——这能说明你想做什么吗?TK,比较Id并不比比较两个对象更有效,但在这里更可靠。