从 asp.net API 中的方法返回后,如何保持线程运行?

Posted

技术标签:

【中文标题】从 asp.net API 中的方法返回后,如何保持线程运行?【英文标题】:How to keep a thread running, after returning from a method in an asp.net API? 【发布时间】:2020-03-21 05:57:03 【问题描述】:

foreach 循环中,我使用Task.Run 来调用一个方法来为每个元素执行一些冗长的操作。

我正在调用的方法是异步方法,但是出于我的目的,我对返回不感兴趣,我想将其他信息返回给客户端。

问题是只有最快的调用完成,其他的被忽略。 如何确保每个调用都在其自己的线程上单独调用,而不会阻止其余代码执行和返回?

foreach (var job in Jobs)

    Task.Run(() => _service.DoLongAsyncCall(job)    

【问题讨论】:

我想这个问题可能是由于应用程序在所有请求的任务完成之前完成造成的。如果是这样,请查看类似的线程:***.com/questions/3840795/… 任务并没有消失,您的问题缺少信息 很难从你的描述中知道你想要什么。不清楚您所说的“我需要在不等待结果的情况下同步执行”是什么意思。因为同步做某事意味着你会等待结果 本文中的建议是唯一对我有用的建议,尤其是方法三。 productiverage.com/…> 您不应该在 IIS 中运行长时间运行的后台作业,因为服务器可能出于不同的原因决定回收,您的作业将被毫不客气地踢到路边。对于这种后台处理,请将您的作业排队到后台进程(不是 IIS)并在那里完成工作。 【参考方案1】:

关闭当前同步上下文状态为null, 因此每个调用都可以独立运行,而不必在当前上下文中运行,从而相互覆盖。

下面的方法正是这样做的。 它在不等待时运行操作而不阻塞主线程。 即使从 API 调用返回,它也会继续运行。

只有在完成所有需要等待的工作后才小心使用此方法, 因为这个调用会干扰常规的异步等待模式。

    public static async Task RunWithoutBlocking(IEnumerable<Func<Task>> actions)
    
        var currentSyncContext = SynchronizationContext.Current;
        try
        
            SynchronizationContext.SetSynchronizationContext(null);
            foreach (var action in actions)
            
                await action();
            
        
        finally
        
            SynchronizationContext.SetSynchronizationContext(currentSyncContext);
        
    `

感谢“Dan's techie ramblings”的有用文章https://www.productiverage.com/i-didnt-understand-why-people-struggled-with-nets-async

【讨论】:

这将一个接一个地运行你的工作,而不是像你的问题那样并行运行。【参考方案2】:

我相信最快的一个正在完成,但其他的实际上还没有完成。尝试以下方法:

List<Task> tasks = new List<Task>();

foreach (var printJob in PrintJobs)

    tasks.add(Task.Run(() => _printService.Print(printJob.Label));


Task.WaitAll(tasks.ToArray());

这将强制主线程阻塞,直到所有 Tasks 完成。

【讨论】:

以上是关于从 asp.net API 中的方法返回后,如何保持线程运行?的主要内容,如果未能解决你的问题,请参考以下文章

从 Axios 请求返回 ASP.NET Core API 中的下载文件

从 ASP.NET Web API 中的控制器返回二进制文件

如何从方法返回asp.net视图中的资源

如何从 ASP.net 5 web api 返回文件

从 ASP.NET Core 中的 API 读取 JWT 令牌

试图从asp.net web api self host中的请求中获取用户代理