在事件处理程序中使用外部资源

时间:2013-12-10 20:56:49

标签: c# multithreading events

考虑以下计划:

class Program
{
    static void Main(string[] args)
    {
        var MyEventThrower = new EventThrower();
        var log= new List<string>();
        log.Add("Log Initialized");
        MyEventThrower.Event += LogEvent;
        MyEventThrower.RaiseEvent();
        foreach (var item in log)
        {
            Console.WriteLine(item);
        }
    }

    static void LogEvent(object sender, EventArgs e)
    {
        log.Add(sender.ToString()); //obviously doesn't work, 
                                    //but this is the sort of 
                                    //behavior I want to achieve.
    }
}

供参考:

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

编辑:我的问题是日志与事件处理程序不在同一个上下文中。我现在看到我可以通过使它成为静态类成员来解决这个问题。

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分: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);
    }
}

这是让你将实现细节包装在logger类中。您甚至可以通过创建自己的ILogger接口并进行不同的Logger实现(即一个用于文件,一个用于控制台等)来进一步扩展。如果您只是计划写入控制台,这可能有点过分。

我喜欢使用类来包装实际日志记录的一件事是实现是在一个点。如果您决定要将所有日志消息都“DEBUG:”添加到您正在记录的消息之前,则只需在一个位置执行此操作。

与原始解决方案相比,我喜欢的另一件事是,您不会将内容添加到列表中,然后再次迭代它们以打印出信息。你正在触发事件时这样做。这样也可以节省内存使用量(即在准备输出之前不要将所有日志消息保存在列表中)。如果我误解了为什么你真的有这个字符串的日志列表,那么我为此道歉。