C#线程之间的通信

时间:2010-04-13 01:08:51

标签: c# multithreading

我正在使用.NET 3.5,并试图解决一个问题(不是我的最高线程专家)。

我有一个Windows服务,它有一个非常密集的进程,一直在运行,我把这个进程放到一个单独的线程上,以便我的服务的主线程可以处理操作任务 - 即服务审计周期,处理配置更改等等。

我通过典型的ThreadStart启动线程到一个关闭进程的方法 - 称之为workerthread。

在这个workerthread上我将数据发送到另一台服务器,正如预期的那样,服务器不时重新启动并且连接丢失,我需要重新建立连接(我通过事件丢失连接通知我) 。从这里开始我的重新连接逻辑,我重新开始运行,但是我很容易注意到的是,我每次都在反复创建这个工作线程(不是我想要的)。

现在,当我失去连接并开始新的连接时,我可以杀死它,但这似乎浪费了资源。

我真正想要做的是,将调用(即我的线程启动方法)编组回到仍在内存中的线程,尽管没有做任何事情。

请发布您有用的任何示例或文档。

感谢。

6 个答案:

答案 0 :(得分:3)

你应该避免杀死工作线程。当您强制终止Win32线程时,并非所有资源都已完全恢复。我相信当Win32线程被杀死时,线程堆栈的保留虚拟地址空间(或者它是根页?)不会被恢复。它可能不会太多,但在长期运行的服务器服务流程中,它会随着时间的推移而累积,最终会降低您的服务。

如果允许线程退出其threadproc以正常终止,则恢复所有资源。

如果后台线程将连续运行(不休眠),您可以使用全局布尔标志来在主线程和后台线程之间传递状态。只要后台线程定期检查此全局标志。如果设置了标志,则线程可以干净地关闭并退出。如果主线程是唯一的编写器而后台线程只读取标志值,则不需要锁定语义。

当后台线程丢失与发送数据的服务器的连接时,为什么不自行执行重新连接?我不清楚为什么主线程需要拆除后台线程来启动另一个线程。

答案 1 :(得分:1)

无论如何,我会杀死(但如果可能的话,优雅地结束)工作线程。一切都被垃圾收集,你可以从头开始。

此服务器重启的频率是多少?如果它经常发生,资源成为一个问题,它可能经常发生。

答案 2 :(得分:1)

您可以使用Singleton模式。在您的情况下,使连接成为静态对象。两个线程都可以访问该对象,这意味着构造并使用它。

主线程可以在需要时构造它,并且只要可用,工作线程就会访问它。

答案 3 :(得分:1)

使用ThreadPool.QueueUserWorkItem来调用方法。此方法从线程池中获取一个线程并启动一个方法。它似乎是在另一个线程上启动方法的任务的理想选择。

此外,当您说“典型的ThreadStart”时,您的意思是说您正在使用Thread参数创建并启动新的ThreadStart,或者您正在创建ThreadStart并致电Invoke就可以了?

答案 4 :(得分:1)

您考虑过BackgroundWorker吗?

根据我的理解,你只需要一个正在工作的线程,除非你需要cancel处理它。

答案 5 :(得分:1)

BackgroundWorker比使用普通线程慢一点,但它可以选择支持CancelAsync方法。
基本上,BackgroundWorker是工作线程的包装器,带有一些额外的选项和事件。

CancelAsync方法仅在设置WorkerSupportsCancellation时有效 调用CancelAsync时,会设置CancellationPending 工作者线程应定期检查CancellationPending以确定是否需要提前退出。

- 的Jeroen