私は MVC3 ベースの Web アプリケーションを開発しています。これは、ある時点で外部データベースから大量のデータをキャッシュする必要があります。処理には 10 ~ 30 分ほどかかります (トラフィックによって異なります) ので、BackgroundWorker に入れます。Webページの特定のボタンをクリックすると、ajaxを使用してコントローラーの他のメソッドにアクセスし、戻り値に応じて適切な情報がユーザーインターフェイスに表示されます。
コントローラ:
if (IsDbLocked())
{
return this.Json(new
{
success = false,
message = "There is already an update requested by other user on the way."
});
}
this.model.DataUpdateBegin();
return this.Json(new { success = true });
モデル:
public void DataUpdateBegin()
{
var backgroundWorker = new BackgroundWorker
{
WorkerSupportsCancellation = false,
WorkerReportsProgress = true
};
backgroundWorker.DoWork += this.DataUpdateWorkerDoWork;
backgroundWorker.ProgressChanged += this.DataUpdaterWorkerProgressChanged;
backgroundWorker.RunWorkerCompleted += this.DataUpdaterWorkerRunWorkerCompleted;
if (this.DataUpdateLockDb(true))
{
backgroundWorker.RunWorkerAsync();
}
}
更新すると、UI がフリーズします。コントローラーのデバッグ中に、BackgroundWorker が起動し、すぐにステートメントを返し続けます (success = true) が、終了するだけで他に何も起こりません (返されたメッセージは Web ページに到達しません)。
他のブラウザ/ユーザーからページを見ることができ、すべて正常に動作しますが、この特定のスレッドは数分間ロックされています (約 5 分後にロックが解除されるため、10 ~ 30 分ではありません - タイムアウト?)
私の質問は、私が間違っていたことと、それを修正する方法です。backgroundWorker がバックグラウンドで実行され、ユーザーが自由にページ内を自由に移動できることを期待しています。また、データベースにエントリを作成し、外部アプリケーションを作成してそれを取得し、すべての作業を (実際のバックグラウンドで) 実行することは、私にとっては選択肢ではありません。