即发即弃任务的观察者

Observer for fire&forget Task

免责声明:我可能有一个坏主意!

我在 ASP.NET 5 上有一个中间件。 该中间件处理请求并启动一个新的 Task。该任务主要用于统计目的。 中间件不关心这个任务的结果。

出于性能原因,我想继续 ASP.NET 管道而不等待 "background" 任务。

我看到了三种实现方法:

1/开始任务,没有await.Wait()。不关心未观察到的异常。

2/ 在“observer”中注册任务。观察者将观察所有任务,直到应用程序结束。

3/ 使用服务总线 and/or 一种工作者角色 / WebJob。

我不喜欢解决方案 1/。

解决方案 3/ 似乎过分了。

解决方案 2/ 对我来说没问题,类似的东西:

public class TaskObserver : IDisposable
{
    private readonly List<Task> _tasks = new List<Task>();
    public void RegisterTask(Task task)
    {
        _tasks.Add(task)
    }

    public void Dispose()
    {
        Task.WaitAll(_tasks.ToArray());
    }
}

// somewhere in the service configuration...
serviceCollection.AddSingleton<TaskObserver>();

Observer 将在最终应用程序中由其容器处理。 我什至可以添加一个 Timer 来定期清理已完成的任务。

2/ 解在 ASP.NET 5 上下文中是否正确?

最重要的是,ASP.NET 不是为执行 不是 HTTP 请求的工作而设计的。有一个 few different ways to try to hack together a fire-and-forget situation(正如我在我的博客上描述的那样),但其中 none 是万无一失的。

另一方面,WebJobs 是为完全 这种情况而设计的。所以最佳答案是"just use WebJobs"。试一试;它们可能没有你想象的那么难。

但是,如果您真的想采用不太可靠的途径在 ASP.NET AppDomain 中进行后台工作,则可以尝试不同程度的黑客攻击。例如,如果您愿意依赖完整的 .NET 框架(而不仅仅是核心),那么您可以使用 HostingEnvironment.QueueBackgroundWorkItem.

Hangfire (google Hangfire.io) 现在有 ASP.NET 核心支持,甚至可以处理异步任务,它正是为此目的而构建的。