c# - .NET 中是否维护异步调用的顺序?使用异步等待实现记录器?

标签 c# async-await

我正在尝试创建一个简单的异步记录器。使日志记录调用非阻塞且尽可能不引人注目的想法。请考虑以下简化代码-

class Logger {
    public async void Log(string message) {
        LogTable log = new LogTable(); //LogTable is an SqlServer table
        log.Timestamp = DateTime.Now;
        log.Message = message;
        log.SomeProp = SomeVariableTimeCalculation();
        var db = new Entities(); //db is an EF6 context
        db.Entry(log).State = EntityState.Added;
        db.LogTables.Add(log);
        await db.SaveChangesAsync();
   }
}    

它可以按如下方式使用(不等待任何 Log(...) 调用)-

class Account
    private readonly Logger logger = new Logger();
    public void CreateAccount(Account acc) {
        logger.Log("CreateAccount Start");
        //Maybe some async operations here
        logger.Log("CreateAccount Validation Start");
        bool isValid = Validate(acc);
        logger.Log("CreateAccount Validation End");
        if(isValid) {
            logger.Log("CreateAccount Save Start");
            acc.Save();
            logger.Log("CreateAccount Save End");
        }
        else {
            logger.Log("Account validation failed");
        }
        logger.Log("CreateAccount End");
    }
}

我的问题是-

  1. 有多个异步Log(...) 调用一个接一个。编译器是否可以选择同时并行运行所有这些?如果是,编译器是否知道维护这些调用的顺序,以便 logger.Log("CreateAccount Validation Start"); 不会在 logger.Log("CreateAccount) 之前结束运行开始");?

  2. 如果编译器不保留顺序,那么除了在 Logger 类中维护一个队列之外,还有其他解决方法吗?

更新:澄清 - 我主要关心的是避免竞争条件,例如,可能导致 logger.Log("CreateAccount Validation Start");logger 之前运行/完成。 Log("CreateAccount Start"); 并在不阻塞 CreateAccount 的情况下调用 Log

最佳答案

Can the compiler potentially choose to run all them in parallel simultaneously?

没有。异步与并行完全不同。

If the compiler doesn't preserve order, then is there a way around it other than maintaining a queue within the Logger class?

编译器会保留顺序(即 await 用于顺序异步代码)。但是,队列仍然不是一个坏主意,因为您可能不想在每次日志记录调用时都访问实际的数据库。

关于c# - .NET 中是否维护异步调用的顺序?使用异步等待实现记录器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41983875/

相关文章:

c# - 如何使用情感图标和文本 Windows Phone 制作聊天消息气泡

c# - 如何使用 C#/.NET 将日期时间转换为时间戳(忽略当前时区)

c# - 使用泛型装箱和拆箱

c# - 我应该使用什么时间数据类型

c# 4.0、async CTP 和 async C# 5.0 兼容吗?

c# - 从 Windows 服务调用时,SetThreadExecutionState 不起作用

c# - 创建带有心跳的任务

javascript - 在不链接回调的情况下等待 getScript

c# - 如何在 ASP.NET 4.5 WebForms 中异步执行两个同步的 I/O 绑定(bind)任务?

javascript - Promise 中的 JS Promise