2015-02-24 25 views
0

我正在构建一个WebApi应用程序,该应用程序将托管在Azure网站中,并在适当情况下使用async调用。但是,要求我使日志记录发生在与调用方法不同的线程中,以便继续处理实际业务逻辑,同时某些“工作任务”处理日志记录。在MVC/WebApi应用程序中将异步与手动启动任务混合是否合适?

一个示例场景是这样的:

请求进入async行动 - >电话await businessComponent.ProcessAsync(args) - 同步_logger.Log(message, args)>电话 - >创建new Task(() => FormatAndWrite(message, args),设置task.ConfigureAwait(false),来电task.Start()

所以我希望有人经验更丰富与async/await和方式ASP.NET处理async/await告诉我他们是否看到上述解决方案的主要问题?这是否可以在处理实际业务逻辑请求时节省时间?

+0

这只是一个可接受的方法,如果可以偶尔错过日志。 – 2015-02-24 16:16:57

+0

这是因为在传入请求完成并返回之前,FormatAndWrite的执行可能不会执行? – IWriteApps 2015-02-24 16:32:00

+0

间接,是的。 ASP.NET将偶尔回收您的应用程序,但如果有请求正在处理,它将不会回收。 – 2015-02-24 16:48:10

回答

0

是的。它可以通过使用多线程处理它来缩短特定的请求(假设您的业务逻辑至少有一些CPU绑定工作要做)。

但是,通过对每个请求使用多个线程,您可以使用相同数量的可用线程同时处理较少的请求。所以这是一个折衷。

如果目标是到工作卸载到ThreadPool使用Task.Run的明确,而不是new Task(...).Start并确保您await它离开async处理请求之前进行。 ASP.Net中的后台任务可以在您不知情的情况下停止。

+0

看到的东西是我试图研究这一点,并遇到了一些文章,指出了3个问题,导致我问我的问题:1.只有使用等待,如果有明显的优势,因为等待在引擎盖下昂贵(这对于我们的日志记录来说太过分了)。2.不要在ASP.NET中将Task.Run与Task.Run混为一谈,因为Task.Run显然会向ThreadPool请求一个它不期望创建的新线程它不是一个新的请求进来。所以我不知道什么是正确的... – IWriteApps 2015-02-24 16:13:59

+0

@IWriteApps 1.我怀疑'等待'比这个阻塞IO操作更昂贵。 3. ThreadPool通常不会创建线程。这是一个已经创建的池。只有在用完它们时才会创建新线程。 – i3arnon 2015-02-24 16:54:11

+0

@IWriteApps真正的问题,正如我理解与Task.Run一样,正如Stephen Cleary所述,如果你的应用程序当前没有处理请求,它可以被回收。通过“等待”从Task.Run返回的任务,您可以保持该请求存活。您也可以不等,但意识到您可能会丢失日志。 – i3arnon 2015-02-24 16:57:21

相关问题