2014-01-15 4 views
1

Я пишу программу, которая может быть легко разделена на несколько отдельных частей. Упрощенно это будет выглядеть следующим образом:Как запустить (создать?) Класс в отдельном потоке?

  • Reader класс будет работать с получением данных из определенного устройства,
  • Analyzer класс будет выполнять вычисления на основе данных, полученных от устройства через регулярные промежутки времени,
  • Form1 класс который выводит пользовательский интерфейс (графическое представление данных, собранных Reader и вывода чисел с помощью Analyzer

Естественно, я хотел бы эти три класса для запуска в сентябре (на отдельных ядрах). Значение - все методы Reader работают в своем потоке, все методы Analyzer работают в своем собственном потоке, а Form1 работает по умолчанию.

Однако все, что приходит на ум использует Thread или BackgroundWorker классов, а затем вместо вызова какой-либо ресурс тяжелый метод на Reader или Analyzer я вместо того, чтобы позвонить

BackgroundWorker.RunWorkerAsync() 

Я полагаю, что это не лучший способ сделать это, не так ли? Я бы предпочел каким-то образом создать класс в отдельном потоке и оставить его там на всю жизнь, но я просто не понимаю, как это сделать ... И я не могу придумать подходящий поисковый запрос, потому что я не нашли ответа, когда я его искал.

EDIT: Спасибо за комментарии, я думаю, что я понимаю, что сам вопрос предполагал, что вы можете создать класс «в потоке» - с подразумеваемым значением «любой метод этого класса, который будет вызван в его потоке »- это не имеет смысла и не может быть сделано.

+0

Вы не выполняете класс в потоке. Поток запускает методы. Из разных классов или многих потоков, вызывающих 1 класс. –

+0

[TLS Dataflow] (http://msdn.microsoft.com/en-us/library/hh228603 (v = vs.110) .aspx) может стать отличным инструментом для такой задачи. – Noseratio

ответ

1

Я думаю, что вы на правильном пути. Вам нужно будет

  • две нити Reader и Analyzer созданные Form1. Они в основном состоят из больших петель, которые работают до некоторого флага stopReader или stopAnalyzer не устанавливаются:

  • два concurrent queues, давайте назовем их readQueue и analyzedQueue. Читатель поместит материал в readQueue, Анализатор будет читать от readQueue и напишите до analyzedQueue, а Form1 будет читать от analyzedQueue.

    void runReader() 
    { 
        while (!stopReader) 
        { 
         var data = ...; // read data from device 
         readQueue.Enqueue(data); 
        } 
    } 
    
    void runAnalyzer() 
    { 
        while (!stopAnalyzer) 
        { 
         Data data; 
         if (readQueue.TryDequeue(out data)) 
         { 
          var result = ...; // analyze data 
          analyzedQueue.Enqueue(result); 
         } 
         else 
         { 
          Thread.Sleep(...); // wait a while 
         } 
        } 
    } 
    
  • Вместо Thread.Sleep, вы могли бы использовать BlockingCollection сделать Analyzer ждать, пока новый элемент данных не имеется. В этом случае вы можете использовать CancellationToken вместо Boolean для stopAnalyzer, так что вы можете прервать BlockingCollection.Take при остановке вашего алгоритма.

+0

Ну, я знаю, что могу сделать бесконечный цикл, я бы предпочел просто создать класс в отдельном потоке.Насколько я понимаю, это невозможно? Я не могу просто «иметь» поток, он должен запускать какой-то метод или он выйдет? Мое устройство работает с callbacks btw, поэтому я действительно не нахожу ничего для чтения данных, но метод класса вызывается с самими данными, переданными как параметр. – Istrebitel

+0

@Istrebitel - я бы сказал, что предложенный выше подход предполагает назначение меток 'runReader' и' runAnalyzer' для потоков читателя и анализатора соответственно. Я не знаю, как сделать поток _own_ объектом класса, т. Е. вы не можете «иметь класс в отдельном потоке». Различные методы в классе могут выполняться на разных потоках. Если ваше устройство работает с обратными вызовами, то код вашего читателя будет выполняться в потоке, связанном с устройством; например. если обратные вызовы поступают из COM-объекта, тогда обратные вызовы выполняются в потоке, на котором был создан COM-объект. – groverboy

+0

@Istrebitel: Неясно, что вы подразумеваете под словом «класс в отдельном потоке». Как говорит groverboy, класс - это всего лишь «контейнер методов и данных». Доступ к данным возможен с помощью * any * thread, и метод может быть вызван любым * нитью. Очевидно, вы можете создавать собственные классы в 'runReader'. – Heinzi

Смежные вопросы