Перенаправление страницы при выполнении медленного Linq.DataContext.SubmitChanges() в ASP.NET

Для интранет-приложения у меня есть функция сохранения веб-страницы, которая может привести к существенным действиям с несколькими таблицами базы данных. Я использую Linq2SQL, и около 20 секунд простоя браузера поглощаются тремя отдельными вызовами Linq.DataContext.SubmitChanges(). Эти вызовы происходят прямо в конце кода, вызываемого обратной передачей SaveButton.

Я хочу, чтобы фактическая работа, необходимая для накопления этих изменений в базе данных, выполнялась в рамках действия кнопки сохранения. Однако, учитывая отсутствие проблем или конфликтов, я хотел бы перенаправить пользователя на другую страницу сразу после этого (чтобы им не приходилось смотреть на экран, делая что-то, что они не могут остановить. Затем, когда пользователь продолжает, я хотел бы позвонить всем SubmitChanges().

Идеальный рабочий процесс:

void btnSaveClick() 
{
    CalculateChangeSetProcedure
    Redirect somewhere...
    SubmitChangesProcedure
}

Итак, моя проблема в том, что Response.Redirect(..., true) просто закроет все. Есть ли способ сделать это с помощью процедур ASP.NET или мне придется делать это асинхронно в другом потоке?


person sh54    schedule 29.04.2011    source источник
comment
Похоже, я не собираюсь менять событие кнопки, а вместо этого работаю над изменением кода отправки БД, чтобы вместо этого использовать SqlBulkCopy максимально прозрачно. Прекрасная ссылка: Реализация SqlBulkCopy в Linq to Sql. Это полностью меняет мое время вставки.   -  person sh54    schedule 29.04.2011
comment
Вы можете опубликовать это как ответ и принять его, если это сработало для вас. Так что вопрос закрыт.   -  person Thea    schedule 01.05.2011


Ответы (2)


Если вы пытаетесь отправить небольшое количество данных, то время простоя у вас ненормальное. Первое, что вы можете сделать, это проверить функцию отправки и посмотреть, есть ли что-то, что вы можете оптимизировать. Например, если вы отправляете 50 строк и вызываете SubmitChanges после каждой из них, это может значительно замедлить работу. Решение в этом случае состоит в том, чтобы подготовить всю дату и отправить ее сразу.

Другой вариант — вызвать службу, которая отправит вам изменения. Таким образом, сохранение будет происходить асинхронно и не будет прерывать пользователя. После завершения службы вы можете получить простое всплывающее окно jQuery или что-то еще, чтобы сообщить пользователю, что сохранение завершено, если это важно.

person Thea    schedule 29.04.2011
comment
Это большой объем данных. 20 секунд на сервере базы данных разработки — это результат нескольких тысяч вставок в несколько таблиц в трех базах данных. Старый код, который я оптимизировал, использовался для отправки множества небольших фрагментов, о чем вы предупреждаете. Я рассматриваю ваш отдельный подход к веб-сервису... - person sh54; 29.04.2011
comment
Прочтите эту статью weblogs.asp.net/stevewellens/archive/2010/04/02/ - person Thea; 29.04.2011
comment
если вставляемые данные слишком велики, то вы должны быть осторожны, чтобы процесс ASP.net был убит по истечении времени ожидания. Одним из возможных решений этого является вызов не веб-службы или другого потока ASP.NET, а вызова службы Windows. Таким образом, у потока не будет тайм-аута. - person Thea; 29.04.2011

Запустите отдельный фоновый поток для вызова SubmitChanges() перед выполнением перенаправления.

e.g.

void btnSaveClick() 
{    
      CalculateChangeSetProcedure
      ThreadPool.QueueUserWorkItem(new WaitCallback(this.SubmitTheStuff), null);
      Redirect somewhere..
}
private void SubmitTheStuff(object obj)
{
      SubmitChangesProcedure
}    
person Hauzi    schedule 29.04.2011
comment
Я попробовал, но не могу остановить Linq.DataContext.SubmitChanges(), когда я переношу его в другой поток. - person sh54; 29.04.2011
comment
Да. Но, по крайней мере, браузер должен перенаправлять, пока SubmitChanges() выполняет свою работу. Что вы имеете в виду под взрывом? Объем памяти? - person Hauzi; 29.04.2011