生成一个执行文件监视的临时线程的好方法

本文关键字:监视 线程 方法 文件 执行 一个 | 更新日期: 2023-09-27 18:17:20

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

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

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

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

理论上,控制器动作将调用外部系统(这是一个web服务(asmx)调用),然后,我想要触发一个将执行最多10分钟的短暂线程,如果它在文件夹中找到.xml文件,它将处理它们。

感谢

—EDIT, Update

Brandon的解决方案正是我所需要的,但是他说要得到任务。延迟方法代码来自另一个stackoverflow问题,来自反编译Async库的人。这对我不起作用,所以我不得不获得Microsoft.CompilerServices.AsyncTargetingPack NuGet包。

生成一个执行文件监视的临时线程的好方法

FileSystemWatcher不需要线程或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);
}