2013-12-10 136 views
0

考慮下面的程序內外部資源使用事件處理程序

public delegate void EventHandler(object sender, EventArgs e) 

public class EventThrower 
{ 
    public event EventHandler Event; 
    protected virtual void OnEvent(EventArgs e) 
    { 
     if (Event!= null) 
     { 
      Event(this, e); 
     } 
    } 
    public void RaiseEvent() 
    { 
     OnEvent(EventArgs.Empty); 
    } 
} 

編輯:在這裏,我的問題是,日誌是不相同的上下文中事件處理程序中。我現在看到,我可以通過將其設置爲靜態類成員來解決這個問題。

+0

預期的行爲是什麼?當我運行你的程序時,它執行'LogEvent'方法。顯然在糾正一些錯別字之後。 –

+0

您能夠在事件處理程序中使用'log.Add()'方法運行程序嗎?在這種情況下,「log」不存在。你怎麼修好它的?另外,我現在會改正錯別字。我在SO問題框中輸入了這個程序,我不應該這樣做= P – JHixson

+0

它們不是**在不同的線程中執行。你很難清楚你想要解決什麼問題,因爲除了使「log」變量成爲一個靜態類成員之外沒有別的。 –

回答

2

最簡單的方法是使用lambda時可以關上名單:

var MyEventThrower = new EventThrower(); 
var log= new List<string>(); 
log.Add("Log Initialized"); 

MyEventThrower.Event += (sender, args) => log.Add(sender.ToString()); 

MyEventThrower.RaiseEvent(); 
foreach (var item in log) 
{ 
    Console.WriteLine(item); 
} 
+0

不錯,我不知道你能做到這一點!我知道必須有這樣的事情。然而,我意識到一個更簡單的解決方案是取得日誌,並使其成爲靜態類成員,但我將來肯定會使用它。 – JHixson

0

我不知道,如果你需要使用你的日誌變量/列表爲別的,所以我做了假設你只需要按照你設計代碼的方式進行日誌記錄。

我建議類似如下:

static void Main() 
{ 
    var logger = new Logger(); 
    logger.Log("Log Initialized"); 

    var MyEventThrower = new EventThrower(); 
    MyEventThrower.Event += (sender, _) => logger.Log(Convert.ToString(sender)); 
    MyEventThrower.RaiseEvent(); 
} 

public class Logger 
{ 
    public void Log(string message) 
    { 
     Console.WriteLine(message); 
    } 
} 

這使你可以換一個記錄器類內部的實現細節。你甚至可以通過創建你自己的ILogger接口和製作不同的Logger實現來進一步擴展(例如,一個用於文件,一個用於控制檯等)。如果你只是打算寫控制檯,這可能是矯枉過正的。

我喜歡使用類來包裝實際日誌記錄的一件事是實現在一個點。如果您決定希望所有日誌消息有「DEBUG:」作爲您記錄的消息的前綴,您只需要在一個位置執行此操作。

與原始解決方案相比,我喜歡的另一件事是,您不會將任何東西添加到列表中,然後再次遍歷它們以打印出信息。您在事件觸發時執行此操作。這也將節省內存使用量(即,在準備輸出它們之前,不會將所有日誌消息保存在列表中)。如果我誤解了爲什麼你真的有這個日誌列表的字符串,那麼我對此表示歉意。

+1

我認爲這是一個很有意思的例子,僅僅是爲了演示從事件接收器中訪問一個對象,而不是說他是如何使用他的程序中的日誌記錄。 – Servy

+0

夠公平的。感謝澄清。 –