0

我有以下情况,我不确定如何最好地处理。

在 ASP.NET MVC 4 系统上,我有一个控制器操作,它调用外部系统(在同一网络中),在 1 到 10 分钟内,将生成 3 个 XML 文件并将它们放在同一服务器上的文件夹中托管 ASP.NET MVC 应用程序的位置。

起初我想使用带有 FileSystemWatcher 的 Windows 服务来监视文件夹中的 XML 文件,但有人要求我提出一个替代解决方案,以防安装 Windows 服务不可行。

我做了很少的线程,所以我不确定理想的方法是什么。

理论上,控制器操作将调用外部系统(它是一个 Web 服务 (asmx) 调用),然后,我想触发一个短期线程,该线程将执行长达 10 分钟,如果它在其中找到 .xml 文件文件夹,它将处理它们。

谢谢

-- 编辑、更新

Brandon 的解决方案完全符合我的需要,但他说要从另一个 stackoverflow 问题中获取 Task.Delay 方法代码,从反编译 Async 库的人那里获取。这对我不起作用,所以我必须获得 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 回答