2015-03-02 213 views
0

我有像这样C#静态对象引用

public class FileLogger 
{ 
    public FileLogger(string typeOfLog) 
    { 
    //implementation 
    } 

    public void LogError(string err) 
    { 
    //implementation 
    } 

    public void LogMessage(string err) 
    { 
    //implementation 
    } 
} 

一类由于这是记录其输出到文件的应用程序日志类,一个本来期望它是一个静态类。但是,你可以看到它不是。然而,它在这样的应用中使用:

多线程由BugetApplication类的分类方法启动。该类中的任何错误都会触发在BugetApplication类的clsf_handleEvent方法中处理的事件。所以多个线程可以分别触发自己的事件。将创建实例变量作为BugetApplication类中的静态变量在这里有什么作用,或者保持它不静态具有相同的效果?我不希望任何一个线程覆盖另一个线程的错误信息。

编辑 只是为了清楚的事情,只会创建一次的BugetApplication类有一个静态变量'静态FileLogger记录器; '它在构造函数中创建一个实例,并将一些值传递给FileLogger类的构造函数。在BugetApplication类中,有一个方法调用Classification类的分类方法。 Classify方法启动各种线程,并在出现任何错误时触发BugetApplication类中处理的事件,以便此clsf_handleEvent方法可对其进行多次调用。

+0

如果您需要线程同步,那么它是否为'静态' – Spo1ler 2015-03-02 10:53:13

+0

感谢您使用'public BugetApplicationClass()'创建每个BugetApplication实例的新记录器实例。你的意思是'静态BugetApplicationClass()' - 只被调用一次的静态ctor? – 2015-03-02 10:54:34

+0

单身人士如何确保日志和记录器的一个剪切实例? – 2015-03-02 11:06:56

回答

2

为什么你认为它会覆盖另一个线程的错误信息?记录器应该只是追加消息,所以不应该有任何覆盖(取决于你如何处理日志记录)。但是有一个潜在的问题 - 根据您的日志记录功能,您可能会阻止对文件的访问。由于该方法适用于外部文件,因此您应该在函数中使用lock

真的没关系,如果类是静态的或不是,问题是并发访问外部资源需要同步多个线程成为线程安全。

lock documentation on msdn

+0

我在FileLogger类中使用log4net并调用其方法。哪个函数应该有锁,什么应该被锁定? – user20358 2015-03-02 11:23:02

+1

log4net是线程安全的,所以你的代码应该是现状(除非你做了一些时髦)。如果您没有使用线程安全库,则必须在打开文件并写入文件的记录器中锁定该部分 – walther 2015-03-02 11:26:45

1

这真的取决于实际执行记录的。当他们使单元测试变得更加困难时,静态类现在不被接受。许多常规以静态或单件(记录器,电子邮件等)实现的设施现在提供了单元测试/ IoC友好的替代方案(例如工厂和界面或虚拟类)。

这些设施的设计通常是客户端应用程序用于交互的前端类和负责同步和实际日志记录(或电子邮件或其他)的异步后端。

问题的关键是前端是否是多线程的。

如果它们不是;你应该为每个线程创建一个新的。在这种情况下,记录器可能必须是使用它的方法的局部变量或参数。

但是,它们通常是多线程和可重入的,因为它们所做的只是将日志消息传递到后端并且没有自己的状态。在这种情况下,它们可以保存为静态变量或应用程序范围的单例,但最好将它们作为单例在IoC容器中实例化并将它们注入到使用它们的类中。这样做使得使用模拟记录器编写单元测试变得容易很多。