[英]C# fire event after return statement
我有一个Log
方法,它创建一个LogMessage
对象,并触发一个事件OnMessage
在调用event
后,该方法返回LogMessage
对象。
是否有可能延迟事件,所以它发生在return语句之后?
我需要这个的原因是因为我希望能够在事件提升之前改变LogMessage
对象。
public class Logger
{
public static event LogMessageCreatedEventHandler OnMessage;
public LogMessage Log(string logLevel, string message)
{
LogMessage logMessage = new LogMessage
{
Message = message,
LogLevel = logLevel,
DateTime = DateTime.UtcNow
};
OnMessage?.Invoke(this, new LogMessageCreatedEventArgs { LogMessage = logMessage });
return logMessage;
}
}
// usage
var logMessage = _logger.Log("Debug", "Product has been created"); <-- the event is invoked now
logMessage.CustomProp.Add("isProductsService", true); <-- this property is not available in the Event Handler
一个想法是使用Task.Delay()
,但我不认为这是一个很好的解决方案。
Task.Delay(1000).ContinueWith(_ => {
OnMessage?.Invoke(this, new LogMessageCreatedEventArgs { LogMessage = logMessage });
});
return message;
使用Task.Delay(1000)
创建竞争条件。 延迟事件直到return
不足,因为调用者可能有或没有足够的时间来及时完成对LogMessage
修改,以便事件获取修改后的属性。
在触发事件之前确保修改已结束的一种方法是在创建事件和触发事件之间插入一段代码。 这可以通过代表来完成:
public static event LogMessageCreatedEventHandler OnMessage;
// By default message preprocessor does nothing
public static Func<LogMessage,LogMessage> Preprocess { get; set; } = m => m;
public LogMessage Log(string logLevel, string message) {
LogMessage logMessage = new LogMessage {
Message = message,
LogLevel = logLevel,
DateTime = DateTime.UtcNow
};
OnMessage?.Invoke(this, new LogMessageCreatedEventArgs {
LogMessage = Preprocess(logMessage)
});
return logMessage;
}
现在,您可以将预处理逻辑添加到Logger
以对LogMessage
进行修改:
Logger.Preprocessor = lm => {
lm.PropertyToBeChanged = newPropertyValue;
lm.AnotherProperty = someOtherValue;
return lm;
};
我需要在“上下文”级别更新属性,而不是在全局级别更新属性,在这里我丢失了创建日志消息的位置的信息。
您可以将Func
作为参数传递给Log
,如下所示:
private static readonly Func<LogMessage,LogMessage> doNothing = m => m;
public LogMessage Log(string logLevel, string message, Func<LogMessage,LogMessage> preprocess = doNothing) {
LogMessage logMessage = new LogMessage {
Message = message,
LogLevel = logLevel,
DateTime = DateTime.UtcNow
};
OnMessage?.Invoke(this, new LogMessageCreatedEventArgs {
LogMessage = preprocess(logMessage)
});
return logMessage;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.