gpt4 book ai didi

返回语句后的 C# 触发事件

转载 作者:太空狗 更新时间:2023-10-30 01:13:38 24 4
gpt4 key购买 nike

我有一个 Log 方法,它创建一个 LogMessage 对象,并触发一个事件 OnMessage

在调用事件后,该方法返回LogMessage对象。

是否可以延迟事件,使其发生在返回语句之后?

我需要这个的原因是因为我希望能够在事件发生之前更改 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 的修改,以便事件获取修改后的属性.

确保在触发事件之前完成修改的一种方法是在创建事件和触发事件之间插入一段代码。这可以通过委托(delegate)来完成:

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;
};

I need to update the property at "contextual" level, rather than on Global level, where I lose the information from where the log message was created.

可以将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;
}

关于返回语句后的 C# 触发事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48974586/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com