Каков наилучший способ передачи данных между параллельными потоками в .NET? - PullRequest
4 голосов
/ 20 сентября 2008

У меня есть два потока, один должен опросить кучу отдельных статических ресурсов в поисках обновлений. Другой должен получить данные и сохранить их в базе данных. Как поток 1 может сообщить потоку 2, что нужно что-то обрабатывать?

Ответы [ 4 ]

7 голосов
/ 20 сентября 2008

Если части данных независимы, то обрабатывайте их как рабочие элементы, которые будут обрабатываться пулом потоков. Используйте пул потоков и 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); 
}
5 голосов
/ 20 сентября 2008

Я использую Monitor.Wait / Pulse в очереди рабочих элементов.

0 голосов
/ 20 сентября 2008

У меня лично были бы события 1 потока, на которые поток 2 может ответить. Управляющий процесс, который инициирует оба потока, может связывать потоки с соответствующими событиями.

0 голосов
/ 20 сентября 2008

Всегда ли должен быть запущен поток "store in the DB"? Похоже, что, возможно, лучшим вариантом (если это возможно) было бы, чтобы поток опроса раскрутил другой поток для сохранения. В зависимости от количества создаваемых потоков, возможно, что использование первого потока опроса использует ThreadPool.QueueUserWorkItem () может быть более эффективным маршрутом.

Для большей эффективности при сохранении в базе данных я бы использовал асинхронный ввод-вывод в БД, а не методы синхронизации.

В любое время вы можете избавиться от необходимости напрямую общаться между двумя потоками. При необходимости собрать вместе несколько примитивов синхронизации, ваш код будет не так легко отладить, и он может привести к некоторым очень тонким условиям гонки, которые приводят к ошибкам типа «один на миллион выполнения» (которые совсем не весело находить / исправлять).

Если второй поток всегда должен выполняться, дайте нам знать, почему с некоторой дополнительной информацией, и мы можем вернуться с более глубоким ответом.

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...