Выполнить хранимую процедуру из формы Windows асинхронно и затем отключить? - PullRequest
20 голосов
/ 04 августа 2009

Я вызываю хранимую процедуру из своего приложения, выполнение которой может занять 30 минут.

Я не хочу, чтобы мой пользователь оставлял приложение открытым в течение всего этого периода времени. Поэтому я хотел бы вызвать sproc, позволить ему летать, и позволить им закрыть приложение и вернуться позже.

Как я могу это сделать?

Ответы [ 8 ]

26 голосов
/ 05 августа 2009

Это на самом деле довольно распространенный сценарий. Вы не можете ничего сделать на основе клиента, потому что клиент может уйти и отключиться, и вы потеряете работу, проделанную до сих пор. Решение состоит в том, чтобы использовать Активация компонента Service Broker : вы создаете службу в базе данных и присоединяете активированную процедуру. В своем приложении (или странице ASP) вы отправляете сообщение в сервис и встраиваете необходимые параметры для вашей процедуры. После фиксации вашего приложения, сообщение активирует процедуру обслуживания. процедура обслуживания считывает параметры из сообщения и вызывает вашу процедуру. поскольку активация происходит на серверном потоке, не связанном с вашим исходным соединением, это надежно. Фактически сервер может даже завершить работу и перезапустить , пока ваша процедура выполняется, и работа будет откатана, а затем возобновлена, поскольку после перезапуска активирующее сообщение снова запустит сервисную процедуру.

Обновление

Я опубликовал подробную информацию о том, как это сделать, включая пример кода в моем блоге: Асинхронное выполнение процедуры .

3 голосов
/ 04 августа 2009

Вы можете использовать BeginExecuteXXX / EndExecuteXXX методы (в зависимости от того, возвращает ли он результат) SqlCommand, передавая делегат обратного вызова.

2 голосов
/ 05 августа 2009

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

2 голосов
/ 05 августа 2009

Если вы действительно хотите полностью закрыть свое приложение, я предлагаю вам определить задание в агенте SQL Server и просто выполнить инструкцию T-SQL, чтобы запустить это задание вручную. Синтаксис:

sp_start_job 
     {   [@job_name =] 'job_name'
       | [@job_id =] job_id }
     [ , [@error_flag =] error_flag]
     [ , [@server_name =] 'server_name']
     [ , [@step_name =] 'step_name']
     [ , [@output_flag =] output_flag]

Задание выполнит вашу хранимую процедуру. Вы должны будете быть немного творческими, чтобы передать любые аргументы. Например, вставьте параметры в таблицу «queue» и попросите задание обработать все строки в очереди.

Вместо задания также должен работать триггер вставки в вашей очереди.

2 голосов
/ 04 августа 2009

Я предлагаю ре-архитектуру. Создайте таблицу «Очередь работ», в которую вы будете записывать запросы на запуск хранимой процедуры. Затем либо предоставьте службу Windows или задание SQL Server, чтобы время от времени проверять рабочую очередь (или будьте очень изобретательны и используйте триггер), чтобы запустить хранимую процедуру. Попросите хранимую процедуру время от времени обновлять ход выполнения в таблице рабочей очереди, и ваш интерфейсный пользователь может посмотреть на это, сообщить пользователю ход выполнения, а затем отобразить результаты, когда они будут выполнены.

1 голос
/ 04 августа 2009

Другой способ, который вы могли бы сделать, - разрешить вашему приложению работать в фоновом режиме (возможно, в области уведомлений), а затем выйти или уведомить о завершении задания. Вы можете использовать это, используя методы BeginExecuteNonQuery и EndExecuteNonQuery, чтобы позволить ему работать в отдельном потоке.

1 голос
/ 04 августа 2009

пусть закрывают приложение и приходят вернуться позже

Если вы собираетесь разрешить им полностью закрыть приложение, вам нужно запустить отдельный .exe или что-то в другом ThreadPool, который выполняет ваш код, вызывая хранимую процедуру. В противном случае ваша нить умрет, когда вы закроете приложение.

0 голосов
/ 05 августа 2009

Главное окно вашего приложения не нужно открывать. Если вы запустили его как вторичный поток, он будет работать до тех пор, пока IsBackground == false. Я обычно предпочитаю делать это через агента SQL Server или как клиент-серверное приложение (ничто не мешает клиент-серверному приложению работать на одном компьютере или даже быть одним и тем же двоичным файлом).

Это было давно ...

using System.Threading;

.....

Thread _t = null;
void StartProcedure()
{
  _t = new Thread(new ThreadStart(this.StartProc));
  _t.IsBackground = false;//If I remember correctly, this is the default value. 
  _t.Start();
}

bool ProcedureIsRunning
{
 get { return _t.IsRunning; } //Maybe it's IsActive. Can't remember. 
}

void StartProc(object param)
{
  //your logic here.. could also do this as an anonymous method. Broke it out to keep it simple. 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...