2

コンテクスト

テーブルといくつかのリモートIISの間でサイトのリストを同期するこの関数があります。

namespace Dashboard.Controllers
{
    public class SiteController : Controller
    {
        public ActionResult Synchronize()
        {
            SiteModel.synchronizeDBWithIIS();

            return Content("Cool.");
        }
    }
}

ダッシュボードの起動時と実行時に、この関数を非同期で呼び出したいと思います。

質問

  • $.get()(jQuery)を実行するか、AsyncResult(ASP.NET)を使用するようにアドバイスしますか?

  • で使用Application_start()される可能性がありGlobal.asaxますか?

  • さらに、同期を高速化するためにこのコントローラーを改善できますか?

4

2 に答える 2

2

上記のどれでもない。これは、ASP.NET アプリケーションで行うべきではありません。この危険性については、次の記事を参照してください。

これは、別のアプリケーションで実行する必要があります。たとえば、Windows タスク スケジューラを使用して、このアプリケーションを定期的に実行すると、この時間のかかる操作を処理してくれます。

ASP.NET アプリケーションでは、ワーカー スレッドを長時間ブロックすることほど悪いことはありません。これを ASP.NET アプリケーションに実装する唯一の可能な解決策は、I/O 完了ポートを使用することです。次に、 AsyncControllerを使用できます。しかし、私が見ることができるのSiteModel.synchronizeDBWithIIS();はブロッキングメソッドであるため、実行できません。

ただしSiteModel、I/O 集中型タスク (CPU 集中型ではない) を実行するための非同期 API を提供した場合は、次のように実装できます。

public class SiteController : AsyncController
{
    public void SynchronizeAsync()
    {
        AsyncManager.OutstandingOperations.Increment();

        SiteModel.GetHeadlinesCompleted += (sender, e) =>
        {
            AsyncManager.OutstandingOperations.Decrement();
        };

        SiteModel.synchronizeDBWithIISAsync();
    }

    public ActionResult SynchronizeCompleted()
    {
        return Content("Cool.");
    }
}

これが完了したら、AJAX 呼び出しを使用して同期アクションを呼び出すか、通常の呼び出しを使用して呼び出しを行うかは問題ではありません。重要なのは、このアクションが非同期になり、ワーカー スレッドをブロックしないことです。これを基になる API に委任します。この API は、現時点で長い I/O 操作を実行するために、ストリーム、ソケット、データベース接続などで BeginXXX、EndXXX メソッドを使用します。API がまだ実装されていない場合は、それを理解することが重要です。このため、同期メソッドを新しいスレッドまたは非同期デリゲートにラップして、そこで実行することはできません。できるということですが、それをしても何も得られません。

注意: これにより操作が高速化されるなどと騙されないでください。そのための奇跡はありません。操作には以前とまったく同じ時間がかかります。実行中に ASP.NET ワーカー スレッドを危険にさらすことがなく、他の要求がより速く実行されるというだけです。

于 2012-07-18T14:25:59.617 に答える
0

この 2 つは異なる目的で使用されます。AsyncResultただし、あなたが説明したことから、メソッド呼び出しを非同期で実行するために使用したいようです。

于 2012-07-18T14:15:52.270 に答える