Подтвердить что ты не робот

Выполнить асинхронную хранимую процедуру из формы окна и затем отключить?

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

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

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

4b9b3361

Ответ 1

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

Обновление

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

Ответ 2

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

Ответ 3

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

Ответ 4

Если вы действительно хотите полностью закрыть приложение, я предлагаю вам определить задание в агенте 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" и обработайте все строки в очереди.

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

Главное окно вашего приложения не должно быть открытым. Если вы запустили его как дополнительный поток, он будет продолжать работать до тех пор, пока 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 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. 
}