0

どのように処理するのが最善なのかわからない次のシナリオがあります。

ASP.NET MVC 4 システムでは、(同じネットワーク内の) 外部システムを呼び出すコントローラー アクションがあり、1 ~ 10 分以内に 3 つの XML ファイルを生成し、それらを同じサーバー上のフォルダーに配置します。 ASP.NET MVC アプリがホストされている場所。

最初は、FileSystemWatcher で Windows サービスを使用して XML ファイルのフォルダーを監視することを考えていましたが、Windows サービスをインストールできない場合に備えて、別の解決策を提案するよう求められました。

私はスレッド化をほとんど行っていないので、これを行う理想的な方法が何であるかはわかりません。

理論的には、コントローラー アクションは外部システムを呼び出します (これは Web サービス (asmx) 呼び出しです)。次に、最大 10 分間実行される短命のスレッドを起動します。フォルダー、それはそれらを処理します。

ありがとう

-- 編集、更新

Brandon のソリューションは、私が必要としているとおりに機能しますが、Async ライブラリを逆コンパイルした人から、別の stackoverflow の質問から Task.Delay メソッド コードを取得すると彼は言います。これではうまくいかなかったため、Microsoft.CompilerServices.AsyncTargetingPack NuGet パッケージを入手する必要がありました。

4

1 に答える 1

2

AFileSystemWatcherは、スレッドや Windows サービスを必要としません。それを作成し、イベント ハンドラーを設定EnableRaisingEventsしてから、true に設定するだけです。次に、10 分後に期限切れになるタイマーを開始し、ウォッチャーを破棄します。何かのようなもの:

private async void RunAfterDelay(TimeSpan delay, CancellationToken token, Action action)
{
    await Task.Delay(delay, token);
    if (!token.IsCancellationRequested)
    {
        action();
    }
}

private void RunWatcher()
{

    var cts = new CancellationTokenSource();
    var watcher = new FileSystemWatcher();
    watcher.Path = "...";
    watcher.Created += (_, e) =>
    {
        if (e.FullPath == "file-you-are-interested-in")
        {
           // cancel the timer
           cts.Cancel();

           // do your stuff
           // ...

           // get rid of the watcher
           watcher.Dispose();
        }
    };

    watcher.EnableRaisingEvents = true;

    // start the timer
    RunAfterDelay(TimeSpan.FromMinutes(10), cts.Token, () =>
    {
        // get rid of the watcher
        watcher.Dispose();

        // do anything else you want to do, like send out failure notices.
    });
}

これにより、ウォッチャーのリッスンが開始され、必要なものが得られた場合、ウォッチャーが破棄されます。タイマーが切れると、ウォッチャーが停止します。

上記は.NET 4.5を対象としています。4.0 をターゲットにしている場合は、まずDelayここに示す実装を取得します: https://stackoverflow.com/a/9068520/674326

次にRunAfterDelay、これに変更します。

private void RunAfterDelay(TimeSpan delay, CancellationToken token, Action action)
{
    TaskEx.Delay(delay, token).ContinueWith(t => action(), TaskContinuationOptions.OnlyOnRanToCompletion);
}
于 2013-06-06T01:12:00.777 に答える