.NET中并发线程之间传递数据的最佳方法是什么?

时间:2020-03-06 14:28:34  来源:igfitidea点击:

我有两个线程,一个需要轮询一堆单独的静态资源以查找更新。另一个需要获取数据并将其存储在数据库中。线程1如何告诉线程2有需要处理的东西?

解决方案

我在工作项队列上使用Monitor.Wait / Pulse。

如果数据段是独立的,则将数据段视为要由线程池处理的工作项。使用线程池和" QueueUserWorkItem"将数据发布到线程。我们应该使用对称线程池并限制生产者和使用者之间必须发生的同步量,从而获得更好的可伸缩性。

例如(来自MSDN):

TaskInfo ti = new TaskInfo("This report displays the number {0}.", 42);

    // Queue the task and data.
    if (ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), ti)) {    
        Console.WriteLine("Main thread does some work, then sleeps.");

        // If you comment out the Sleep, the main thread exits before
        // the ThreadPool task has a chance to run.  ThreadPool uses 
        // background threads, which do not keep the application 
        // running.  (This is a simple example of a race condition.)
        Thread.Sleep(1000);

        Console.WriteLine("Main thread exits.");
    }
    else {
        Console.WriteLine("Unable to queue ThreadPool request."); 
    }

// The thread procedure performs the independent task, in this case
// formatting and printing a very simple report.
//
static void ThreadProc(Object stateInfo) {
    TaskInfo ti = (TaskInfo) stateInfo;
    Console.WriteLine(ti.Boilerplate, ti.Value); 
}

是否始终需要运行"存储在数据库中"线程?似乎最好的选择(如果可能的话)可能是让轮询线程旋转另一个线程来进行保存。但是,取决于正在创建的线程数,可能是让第一个轮询线程使用ThreadPool.QueueUserWorkItem()可能是更有效的途径。

为了提高效率,在保存到数据库时,我将在数据库上使用异步I / O,而不是使用同步方法。

只要我们可以避免必须直接在两个线程之间进行通信,就应该这样做。必须将一些同步原语放在一起,代码将不那么容易调试,并且可能引入一些非常微妙的竞争条件,这些竞争条件会导致"一次执行百万次"类型的错误(很难找到/修复)。

如果第二个线程总是需要执行,请通过更多信息让我们知道为什么,我们可以返回更深入的答案。

祝你好运!

我个人将线程1引发事件,线程2可以响应。可以通过启动两个线程的控制过程将线程连接到适当的事件。