C# 如何检查函数是否在特定线程上被调用?
如果我有一个线程,它是主应用程序线程和一个辅助线程。如何检查线程B中是否调用了函数 基本上,我正在尝试实现以下代码snippit: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
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”子句是否需要阻塞、激发和遗忘,或者更复杂的东西
- 如何处理超时、死锁等问题
//调用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并不比比较两个对象更有效,但在这里更可靠。