簡體   English   中英

返回語句后的C#fire事件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM