2010-08-03 3 views
5

У меня есть хранимая процедура, которая записывает резервную копию конкретной базы данных. Я вызываю этот SP в приложении C#/Windows Forms asynchrounously. Вот код отрезала:SQL Server2008: BeginExecuteNonQuery/EndExecuteNonQuery Задача

IAsyncResult result = command.BeginExecuteNonQuery(); 
while (!result.IsCompleted) 
{ 
    System.Threading.Thread.Sleep(1000); 
    ... 
} 
command.EndExecuteNonQuery(result)); 

Через некоторое время программа выходит из цикла, потому что IsCompleted = истина и вызывает EndExecuteNonQuery. Проблема в том, что задание еще занято и EndExecuteNonQuery is заблокирован! Это вызывает тайм-аут сервера через несколько минут. Кажется, что значение IsCompleted не соответствует соответственно тому, что не так с IsCompleted? Как я могу добиться того, что моя программа распознает «реальный статус работы» ?

+1

есть причина, почему вы не используете перегрузки обратного вызова для BeginExecuteNonQuery и ждать, пока обратный вызов будет вызван до вызова EndExecuteNonQuery? – btlog

ответ

3

Убедитесь, что хранимая процедура ничего не печатает и не имеет счетных отчетов (SET NOCOUNT ON). Асинхронные вызовы TDS обращаются к первому адресу пакет, отправленный сервером, но этот пакет может быть промежуточным результатом (как в 1 row updated) и случаться долго, задолго до фактического завершения. Это сосать? Да. Можете ли вы что-нибудь сделать? Нет.

Как примечание стороны, это гораздо более эффективным, чтобы просто пройти обратный вызов к BeginExecute (...):

// Set form's state to 'executing', 
// eg. Button.Enabled = false; label.Text = 'Executing'; 
command.BeginExecuteNonQuery((asyncstate)=> 
{ 
    try 
    { 
     command.EndExecuteNotQuery(); 
    } 
    catch(SqlException ex) 
    { 
    ... 
    } 
    // Reset the form's state to 'Ready' 
    Invoke (()=> 
    { 
    // eg. Button.Enabled = true; label.Text = 'Ready'; 
    } 
} 
Смежные вопросы