Несколько асинхронных операций SqlClient - Ищем хороший пример - PullRequest
2 голосов
/ 16 июня 2009

Я использую асинхронные операции в моем клиенте WinForms с самого начала, но только для некоторых операций. Когда ExecuteReader или ExecuteNonQuery завершается, делегат обратного вызова срабатывает, и все работает просто отлично.

У меня два вопроса:

1) Какова лучшая структура для решения этой проблемы в реальной системе? Все примеры, которые я видел, являются игрушечными примерами, когда форма обрабатывает завершение операции и затем открывает устройство чтения данных на EndExecuteReader. Конечно, это означает, что форма более тесно связана с базой данных, чем обычно. И, конечно же, форма всегда может легко вызвать .Invoke на себя. Я настроил все мои асинхронные объекты для наследования от класса AsyncCtrlBlock<T> и имею форму и все делегаты обратного вызова, предоставленные конструктору асинхронных объектов в моем DAL.

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

Ответы [ 2 ]

0 голосов
/ 20 апреля 2012

Если вы используете .Net 4, это было бы идеальным приложением TPL! Вы можете разделить ваш код на такие задачи:

TaskScheduler uiScheduler = GetUISheduller();
SqlCommand command1 = CreateCommand1();

Task<SqlDataReader> query1 = Task<SqlDataReader>.Factory.FromAsync(command1.BeginExecuteReader, command1.EndExecuteReader, null);
query1.ContinueWith(t => PopulateGrid1(t.Result), uiScheduler);

SqlCommand command2 = CreateCommand2();
query1.ContinueWith(t => Task<SqlDataReader>.Factory.FromAsync(command2.BeginExecuteReader, command2.EndExecuteReader, null)
      .ContinueWith(t => PopulateGrid2(t.Result), uiScheduler);
0 голосов
/ 25 июня 2010

относительно 2)

делает первую фазу вашей модели заполненной асинхронной. у тебя будет что-то подобное


FisrtCall();
AsyncResult arPh1 = BeginPhaseOne(); //use results from first call
SecondCall();
EndPhaseOne(arPh1); //wait until phase one is finished
PhaseTwo(); //proceed to phase two

...