Потоки и асинхронные операции в C #
Я старая собака, пытающаяся выучить новый трюк. Я очень хорошо знаком с языком PowerBuilder, и на этом языке, когда вы хотите что-то делать асинхронно, вы порождаете объект в новом потоке. Я повторю это:весь объект создается в отдельном потоке и имеет другой контекст выполнения, Любые и все методы этого объекта выполняются в контексте этого отдельного потока.
Что ж, теперь я пытаюсь реализовать асинхронное выполнение с использованием C #, и модель потоков в .NET кажется совершенно другой для меня. Похоже, что я создаю экземпляры объектов в одном потоке, но я могу указать (для каждого вызова), что определенные методы выполняются в другом потоке.
Разница кажется тонкой, но меня это расстраивает. Мое старомодное мышление говорит: «У меня есть помощник по имени Боб. Боб уходит и делает вещи». Мышление новой школы, если я правильно понимаю, это «Яя Боб. Если мне нужно, я иногда могу потер живот и погладить головув то же время«.
Моя реальная проблема кодирования: я пишу интерфейсный движок, который принимает сообщения через TCP, анализирует их в пригодные для использования данные, а затем помещает эти данные в базу данных. «Разбор» сообщения занимает примерно одну секунду. В зависимости от проанализированных данных, операция с базой данных может занять менее секунды или может занять десять секунд. (Все время выдумано, чтобы прояснить проблему.)
Мое старомодное мышление говорит мне, что мой класс базы данных должен жить в отдельном потоке и иметь что-то вродеConcurrentQueue
, Он будет просто вращаться в этой очереди, обрабатывая все, что может быть там. Парсер, с другой стороны, должен был бы помещать сообщения в эту очередь. Эти сообщения будут (делегаты?) Такими вещами, как «Создать заказ на основе данных вthis object
"или" Обновить заказ на основе данных вthis object
Msgstr "Возможно, стоит отметить, что я действительно хочу обрабатывать" сообщения "в" очереди "в строгом однопоточном порядке FIFO.
По сути, мое подключение к базе данных не всегда может идти в ногу с моим парсером. Мне нужен способ убедиться, что мой синтаксический анализатор не замедляется, пока процессы моей базы данных пытаются наверстать упущенное. Совет?
- редактировать: с кодом! Все и все говорят мне, чтобы использоватьBlockingCollection
, Так воткраткое объяснение конечной цели и кода для ее достижения:
Это будет служба Windows. При запуске он порождает несколько «сред», причем каждая «среда» содержит один «рабочий базы данных» и один «интерфейс». «Интерфейс» будет иметь один «парсер» и один «слушатель».
class cEnvironment {
private cDBWorker MyDatabase;
private cInterface MyInterface;
public void OnStart () {
MyDatabase = new cDBWorker ();
MyInterface = new cInterface ();
MyInterface.OrderReceived += this.InterfaceOrderReceivedEventHandler;
MyDatabase.OnStart ();
MyInterface.OnStart ();
}
public void OnStop () {
MyInterface.OnStop ();
MyDatabase.OnStop ();
MyInterface.OrderReceived -= this.InterfaceOrderReceivedEventHandler;
}
void InterfaceOrderReceivedEventHandler (object sender, OrderReceivedEventArgs e) {
MyDatabase.OrderQueue.Add (e.Order);
}
}
class cDBWorker {
public BlockingCollection<cOrder> OrderQueue = new BlockingCollection<cOrder> ();
private Task ProcessingTask;
public void OnStart () {
ProcessingTask = Task.Factory.StartNew (() => Process (), TaskCreationOptions.LongRunning);
}
public void OnStop () {
OrderQueue.CompleteAdding ();
ProcessingTask.Wait ();
}
public void Process () {
foreach (cOrder Order in OrderQueue.GetConsumingEnumerable ()) {
switch (Order.OrderType) {
case 1:
SuperFastMethod (Order);
break;
case 2:
ReallySlowMethod (Order);
break;
}
}
}
public void SuperFastMethod (cOrder Order) {
}
public void ReallySlowMethod (cOrder Order) {
}
}
class cInterface {
protected cListener MyListener;
protected cParser MyParser;
public void OnStart () {
MyListener = new cListener ();
MyParser = new cParser ();
MyListener.DataReceived += this.ListenerDataReceivedHandler;
MyListener.OnStart ();
}
public void OnStop () {
MyListener.OnStop ();
MyListener.DataReceived -= this.ListenerDataReceivedHandler;
}
public event OrderReceivedEventHandler OrderReceived;
protected virtual void OnOrderReceived (OrderReceivedEventArgs e) {
if (OrderReceived != null)
OrderReceived (this, e);
}
void ListenerDataReceivedHandler (object sender, DataReceivedEventArgs e) {
foreach (string Message in MyParser.GetMessages (e.RawData)) {
OnOrderReceived (new OrderReceivedEventArgs (MyParser.ParseMessage (Message)));
}
}
Это компилируется. (ПЕРЕВОЗИТЕ ЭТО!) Но значит ли это, что я делаю это правильно?