此修改是否使我的方法异步运行

Mri*_*boj 1 c# asynchronous task-parallel-library async-await

以下是记录器调用,即阻塞:

public static void Info(Category category, SubLevel subLevel, object message)
{
    CommonLogger?.Info($"{category}, {(int) subLevel}, {message}");
}
Run Code Online (Sandbox Code Playgroud)

我想让它成为异步执行,因此我做了以下修改,因为根据我的理解有Async-Await for void return方法,就像当前的一个不是一个好的策略:

public static void InfoAsync(Category category, SubLevel subLevel, object message)
{
    Task.Run(() => CommonLogger?.Info($"{category}, {(int)subLevel}, {message}"));
}
Run Code Online (Sandbox Code Playgroud)

代码背景 -

  • 使日志记录以异步方式运行
  • 它是Fire和Forget,主要业务逻辑分开进行

我的问题是:

  1. 我做出这个改变是否正确?

  2. 还有更好的方法,做同样的事情吗?

Yuv*_*kov 5

此修改是否使我的方法异步运行?

不,它没有.并发和并行是两个不同的概念.人们倾向于使并发和并行可互换,但实际上并非如此.您的代码将其他执行单元并行运行,但操作本身并非异步.如果您真的想进行异步操作,则可以使用异步IO来写入底层记录器.

我做出这个改变是否正确?

我会说没有.这称为异步过同步反模式(请参阅链接以获得对此含义的详尽解释).我会避免这种模式,因为它会产生错误的异步感.您的方法实际上并不是异步,真正的异步方法不需要使用额外的线程池线程.

还有更好的方法,做同样的事情吗?

是的,根本就不要这样做.让这个方法的调用者显式调用,Task.Run以便他们知道所述委托将在线程池上执行.或者甚至更好,在记录器实现中使用异步IO.毕竟,我假设这可能会写入底层文件或执行某种网络操作来通过网络发送日志.如果是这样,请利用真正的异步API.

  • @MrinalKamboj是的. (2认同)
  • @JᴀʏMᴇᴇ不,没有关于在线程池线程上排队委托的"异步".随意详细解释为什么我的答案很糟糕,也许我可以改进它. (2认同)
  • @MrinalKamboj您可以将[async appenders](https://www.nuget.org/packages/Log4Net.Async/)用于log4net. (2认同)