我正在尝试创建一个简单的异步记录器。使日志记录调用非阻塞且尽可能不引人注目的想法。请考虑以下简化代码-
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");
}
}
我的问题是-
有多个异步
Log(...)
调用一个接一个。编译器是否可以选择同时并行运行所有这些?如果是,编译器是否知道维护这些调用的顺序,以便logger.Log("CreateAccount Validation Start");
不会在logger.Log("CreateAccount) 之前结束运行开始");
?如果编译器不保留顺序,那么除了在 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/