C# 生成执行文件监视的临时线程的好方法?

C# 生成执行文件监视的临时线程的好方法?,c#,asp.net-mvc,multithreading,asp.net-mvc-4,C#,Asp.net Mvc,Multithreading,Asp.net Mvc 4,我有下面的情况,我不确定如何最好地处理 在ASP.NET MVC 4系统上,我有一个控制器操作,它调用一个外部系统(在同一网络中),该系统将在1到10分钟内生成3个XML文件,并将它们放在ASP.NET MVC应用程序所在的同一服务器上的文件夹中 起初,我考虑使用Windows服务和FileSystemWatcher来监视文件夹中的XML文件,但有人要求我提出一个替代解决方案,以防安装Windows服务不可行 我很少使用线程,所以我不确定理想的方法是什么 理论上,控制器操作将调用外部系统(这是一

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

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

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

我很少使用线程,所以我不确定理想的方法是什么

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

谢谢

--编辑、更新


Brandon的解决方案正是按照我所需要的方式工作的,但他说要从另一个stackoverflow问题中获取Task.Delay方法代码,该问题来自反编译异步库的人员。这对我不起作用,因此我必须获得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
的实现,如下所示:

然后将
RunAfterDelay
更改为:

private void RunAfterDelay(TimeSpan delay, CancellationToken token, Action action)
{
    TaskEx.Delay(delay, token).ContinueWith(t => action(), TaskContinuationOptions.OnlyOnRanToCompletion);
}

你好,布兰登。我使用的是.NET4.0,而不是4.5,所以我认为async和await不可用。是否可以将代码调整为不使用AsyncWait?MVC4是为.NET4.5设计的。也许你正在.NET 4上使用MVC 3?不,Stephen,我的目标是ASP.NET MVC 4上的.NET 4.0。试试看:)@GR7-我在底部添加了一些建议,以建议对.NET4.0进行更改。非常感谢您对Brandon的帮助。让我来简单介绍一下,如果可行的话,我会将答案标记为:)Windows服务肯定是处理这个问题的更好方法。但是,如果你真的需要在ASP.NET中使用它,那就谈谈如何装配它。@StephenCleary,我同意,唯一的问题是拥有一个Windows服务(我们已经拥有了,如果可以的话,我们只是想把它从等式中去掉)是另一个额外的失败点,需要配置其他东西,为它安装程序,布兰登的解决方案非常适合我们的需要。你读过我链接的博文吗?我不会用“完美工作”这个词。。。“极度危险”更适合我。我确实读过,斯蒂芬,它不是100%安全的,但我想说它是99%,至少在我的场景中是这样。我认为Phil是一个伟大的开发人员,如果他开发并使用了这个东西(同时也为一个涉及ASP.NET内部结构的开发人员提供了建议),我会说使用它是足够安全的,不是吗?Phil在写那篇博文时,他是ASP.NET MVC框架的高级项目经理。因此,如果他使用诸如“危险”、“狂野”、“邪恶”和“不受支持”之类的术语,那么我会带着适当的恐惧来解决问题。