19

無限のwhileループを実行する必要があり、で実行を開始したいと思いglobal.asaxます。私の質問は、どのように正確にそれを行うべきかということです。新しいスレッドを開始する必要がありますか、それとも非同期とタスクなどを使用する必要がありますか?whileループ内で行う必要があります await TaskEx.Delay(5000);

他のプロセスをブロックしたり、メモリリークを発生させたりしないようにするには、どうすればよいですか?

VS10、AsyncCTP3、MVC4を使用しています

編集:

 public void SignalRConnectionRecovery()
        {
            while (true)
            {
                Clients.SetConnectionTimeStamp(DateTime.UtcNow.ToString());
                await TaskEx.Delay(5000);
            }
        }

私がする必要があるのは、アプリケーションが利用可能である限り、これをシングルトンインスタンスとしてグローバルに実行することです。

編集:解決済み

これはGlobal.asaxの最終的な解決策です

protected void Application_Start()
{
    Thread signalRConnectionRecovery = new Thread(SignalRConnectionRecovery);
    signalRConnectionRecovery.IsBackground = true;
    signalRConnectionRecovery.Start();

    Application["SignalRConnectionRecovery"] = signalRConnectionRecovery;
}


protected void Application_End()
{
    try
    {
        Thread signalRConnectionRecovery = (Thread)Application["SignalRConnectionRecovery"];
        if (signalRConnectionRecovery != null && signalRConnectionRecovery.IsAlive)
        {
            signalRConnectionRecovery.Abort();
        }
    }
    catch
    {
            ///
    }
}

非同期ワーカーの使用方法に関するこの素晴らしい記事を見つけました:http: //www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

そしてこれ: http ://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

しかし、私のニーズにはこれが完璧だと思います:http: //forums.asp.net/t/1433665.aspx/1

4

5 に答える 5

15

ASP.NETは、この種の要件を処理するようには設計されていません。常に実行するものが必要な場合は、Windowsサービスを作成することをお勧めします。

アップデート

ASP.NETは、長時間実行されるタスク用には設計されていません。HTTPリクエストに迅速に応答するように設計されています。Cyborgx37の回答を参照するか、スレッドを使用してIISで長時間実行されるジョブを実行できますか?いくつかの理由で。

アップデート

ついにSignalRを使用しているとおっしゃいましたが、ASP.NET内でSignalRをホストしようとしているようです。これは間違った方法で行われていると思います。プロジェクトwikiで参照されているNuGetパッケージの例を参照してください。この例では、を使用してタスクを管理します。IAsyncHttpHandler

于 2012-06-01T14:51:18.907 に答える
10

global.asaxでスレッドを開始できますが、実行されるのはasp.netプロセスがリサイクルされるまでです。これは、少なくとも1日に1回、または誰もサイトを使用しない場合に発生します。プロセスがリサイクルされた場合、スレッドがagianで再起動される唯一の方法は、サイトにヒットしたときです。そのため、スレッドは継続的に実行されていません。

継続プロセスを取得するには、Windowsサービスを開始することをお勧めします。

「処理中」のソリューションを実行する場合、それは実際に何を実行しているかによって異なります。スレッド自体は、メモリやデッドロックの問題を引き起こしません。アプリケーションが停止したときにスレッドを停止するには、メガニズムを追加する必要があります。そうしないと、スレッドが停止するのを待つため、再起動に時間がかかります。

于 2012-06-01T14:53:58.960 に答える
5

これは古い投稿ですが、私がこれについて説明していたので、.NET4.5.2にはQueueBackgroundWorkItemを使用してそれを行うネイティブな方法があることを報告したいと思います。

この投稿を見てください:https ://blogs.msdn.microsoft.com/webdev/2014/06/04/queuebackgroundworkitem-to-reliably-schedule-and-run-background-processes-in-asp-net/

マリアーノC

于 2014-07-31T11:14:20.020 に答える
2

whileループで何を達成しようとしているかによって異なりますが、一般に、これはWindowsサービスが最良の答えであるような状況です。Windowsサービスをインストールするには、Webサーバーの管理者権限が必要です。

無限ループを使用すると、Windowsメッセージポンプに関して多くの問題が発生します。これは、アプリケーションが何も「実行」していない場合でも、Windowsアプリケーションを存続させるものです。それがなければ、プログラムは単に終了します。

無限ループの問題は、アプリケーションが何かを「実行」してスタックし、他のアプリケーション(またはスレッド)がそのことを「実行」できないことです。WindowsフォームのDoEventsなど、いくつかの回避策がありますが、応答性とリソース管理に関しては、すべてに重大な欠点があります。(小さなLOBアプリケーションでは受け入れられますが、Webサーバーでは受け入れられない場合があります。)whileループが別のスレッド上にある場合でも、使用可能なすべての処理能力を使い果たします。

非同期プログラミングは、データベースが結果を返すのを待ったり、プリンターがオンラインになるのを待ったりするなど、長時間実行されるプロセス向けに設計されています。このような場合、whileループではなく、長い時間がかかるのは外部プロセスです。

ウィンドウサービスが不可能な場合は、独自のメッセージポンプを使用して別のスレッドを設定するのが最善の策だと思いますが、少し複雑です。Webサーバーで実行したことはありませんが、アプリケーションを起動できる可能性があります。これにより、メッセージポンプが提供され、Windowsイベントなどに応答できるようになります。唯一の問題は、Windowsアプリケーション(WPFまたはWinForms)を起動することです。これは、Webサーバーでは望ましくない場合があります。

何を達成しようとしていますか?あなたがそれについて行くかもしれない別の方法はありますか?

于 2012-06-01T15:06:41.897 に答える
1

非同期ワーカーの使用方法に関するこの素晴らしい記事を見つけました。試してみます。http://www.dotnetfunda.com/articles/article613-background-processes-in-asp-net-web-applications.aspx

そしてこれ: http ://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6

しかし、私のニーズにはこれが完璧だと思います:http: //forums.asp.net/t/1433665.aspx/1

于 2012-06-01T15:39:23.010 に答える