1

状況によっては、実行に数分かかるアクション (コントローラー アクション) があります。メッセージ、スピナー、進行状況バーなど、アクションが実行中であることをユーザーに視覚的に示したいと考えています。問題は、アクションが完了したことをフロントエンドで「検出」する方法を理解するのに苦労していることです。

これについて少し調べた後、「 ASP.NET MVC 4 での非同期メソッドの使用」というタイトルの記事を偶然見つけました。非同期アクションと .NET タスクの使用について説明します。それは良いもののように見えます、そして私はそれを研究するのにしばらく時間を費やすつもりですが、私はその概念にあまりにも慣れていないので、それが私が望むものを与えるかどうかを本当に理解することはできません.

SO コミュニティへの私の質問は、非同期アクションとタスクの経験が豊富な場合、アクションの実行中にユーザーに視覚的なフィードバックを提供するのに役立ちますか? それとも、間違った道を歩み始めていますか?

編集:

皆様、ご回答ありがとうございます。こちらからの返信が遅くなり申し訳ありません。これを投稿した後、私はこの状況が少し間違っていることに気付きました。私が本当に必要としているのは、PDF を生成してブラウザーに返す FileResult であり、ファイルの生成中に視覚的なインジケーターをユーザーに表示することです。

私の意見では、これはまったく別の質問です。というわけで、別の質問として投稿します。

4

3 に答える 3

2

非同期コントローラーを使用すると、IIS 要求スレッドが解放されますが、問題の解決には役立ちません。一度に多数の実行時間の長いユーザー リクエストが来ること (IIS リクエスト プールを枯渇させるのに十分なほど) についてまだ心配していない場合は、おそらくこの分野で多くの調査を行う必要はありません。

従来の Post、Redirect、Get フローを使用している場合は、投稿時にスピナーを簡単に表示できます。このスピナーは、ブラウザーが応答を取得して新しいページにリダイレクトすると消えます。

非同期 JavaScript を使用している場合は、呼び出しでスピナーを表示し、完了ハンドラーで非表示にすることができます。

いつでもアプリ ドメインをリサイクルできるため、IIS から独自のバックグラウンド タスクやスレッドを開始しようとしないことをお勧めします。ユーザー リクエストがあると、通常はドレインを停止しますが、開始した追加のバックグラウンド タスクについては認識しません。オブジェクトを IIS に登録して、アプリ ドメインを破棄する前に最初に通知することができますが、IIS が続行するまで最大 30 秒間しか待機できません。あなたの作業は通常これよりも時間がかかるため、このより複雑なルートはおそらくうまく機能せず、コードが少し複雑になることをお勧めします.

それは本当にあなたの要件に帰着します。アプリケーションの使用を継続する前に、作業が完了するまでユーザーを待たせても問題ないでしょうか?それとも、作業が完了するのを待っている間も対話を継続できるようにする必要がありますか?

それらを待たせることができる場合は、投稿、リダイレクト、取得パターンと、送信時にポップアップするモーダル スピナーを使用します。

ユーザーが作業を継続できる必要がある場合は、PartialResponse アクションと、非モーダル スピナーを表示および非表示にして作業が進行中であることを示すハンドラーを使用した AJAX 呼び出しが必要になります。

于 2014-01-31T23:06:01.267 に答える
0

単純にページを作成してから、アクションへの AJAX リクエストを開始することができます。リクエストを開始するときは、スピナーを表示します。

AJAX リクエストが成功またはエラーになったときに、スピナーを非表示にします。

このアプローチでは、UI を拘束していないため、Action メソッドを非同期にする必要はありません。

于 2014-01-31T22:50:56.483 に答える
0

これは、UI スレッドをブロックしてユーザーに視覚的なフィードバックを与えることを避けるために、実行時間の長いプロセスで私が取ったアプローチの例です。

レポートの生成例を示します。これには .net 4.5 が必要です。

タスクを返すレポート生成処理の周りにメソッドを作成します。

例として、以下を参照してください。

private Task RunReport() 
{
    return Task.Run(() => 
              // The below should contain your generate report code
              Thread.Sleep(5000)
     );
}

次に、Actionリターンをタスクにしawaitて、レポートを呼び出す前にを入れます。

これにより、UI スレッドのブロックが解除され、ユーザーはレポートの生成中にサイトを引き続き使用できるようになります。コンテンツは、処理が終了したときにページに返されるものです。

[HttpPost]
public async Task<ActionResult> RequestReportGen()
{
    await RunReport();
    // Add your link to the report in the content below
    return Content("Report generated!";
}

次の JavaScript ライブラリを含めます。

<script src="@Url.Content("~/Scripts/jquery-1.8.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

LoadingElementId次に ajax フォームを使用してメソッドに投稿します。 (待機中の表示) とUpdatedTargetId(完了メッセージの表示) に注意してください。

 @using (Ajax.BeginForm("RequestReportGen", "Home", new AjaxOptions { UpdateTargetId = "result", LoadingElementId="loading" }))
 {
        <div id="loading" style="display:none;">Generating Report...</div>
        <div id="result"></div>
        <input type="submit" />
}

上記の方法を使用すると、UI スレッドがブロックされず、読み込み時と完了時にメッセージがユーザーに中継されるため、ユーザーは引き続きサイトを使用できます。

于 2014-01-31T23:07:36.747 に答える