C#Web API在类之间共享日志类 - ThreadStatic Singleton

时间:2014-07-29 16:40:43

标签: c# variables asp.net-web-api

我正在使用C#构建Web API。在Web API中,我有多个功能。我在用于分割代码的同一个项目中也有其他类。 在API中,我想要一个可以在代码运行时添加数据的类,而不管正在运行什么代码。

用例: 在调用开始时,我想设置一个日志类,它将能够存储信息,以便我在finally块中的数据库中插入。代码中的任何地方我都希望能够在此类中添加信息。一开始我会添加有关变量的信息。在中间我会添加程序执行的操作,如果发生错误,则会发生有关错误的特定信息。最后我会设置执行时间。 我相信如果我声明这个lg类是静态的,那么如果同时处理多个api,信息可能会改变。

我想我的问题是这样的:我如何创建一个在Web API中使用线程安全的“全局”类?

编辑:我需要将此类存储在我的数据库中。要使用log4net,我需要编写一个带有自定义SQL的自定义日志功能,以便将内容插入到我的数据库中

public string UserName { get; set; }
public string Endpoint { get; set; }
public string Response { get; set; }
public DateTime RequestTime { get; set; }
public DateTime ResponseTime { get; set; }
public string ServiceDescription { get; set; }
public string Controller { get; set; }
public string Version { get; set; }
public string ApplicationDescription { get; set; }
public string ApplicationVersion { get; set; }
public string Param1 { get; set; }
public string Param2 { get; set; }
public string Param3 { get; set; }
public string Param4 { get; set; }
public string Param5 { get; set; }
public string Param6 { get; set; }
public string Param7 { get; set; }
public string Param8 { get; set; }
public string Param9 { get; set; }
public string ParamBlob { get; set; }
public string IPAddress { get; set; }

编辑(解决方案):在Batavia回答之后,我发现单身就是可行的方法。经过测试,我发现这不是线程独立的。因此,当我制作2个线程时,两个线程都编辑了相同的数据,并且数据在两个线程之间混合。我解决这个问题的方式是:

public sealed class Logger
{
    [ThreadStatic]
    private static Logger instance = null;
    private static readonly object padlock = new object();
    public int test;
    Logger()
    {
    }

    public static Logger Instance
    {
        get
        {
            if (instance == null)
            {
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new Logger();
                    }

                }

            }
            return instance;
        }
    }
}

以下测试程序用于测试:

    var t = new Thread(_ =>
    {
        var x = Logger.Instance;
        x.test = 2;
        Console.WriteLine("t " + x.test);
        Thread.Sleep(30);
        Console.WriteLine("t after " + x.test);
    });
    var t1 = new Thread(_ =>
    {
        var y = Logger.Instance;
        y.test = 3;
        Thread.Sleep(10);
        Console.WriteLine("t1 " + y.test);
    });
    t.Start();
    t1.Start();
    Console.ReadLine();

2 个答案:

答案 0 :(得分:2)

我会使用log4net来记录您的日志。我用它非常成功。它非常强大,可以记录到文件或数据库。有关配置示例,请参阅http://logging.apache.org/log4net/release/config-examples.html

更新我认为最简单的方法是在调用开始时创建该类的实例,然后将其传递给其他各种类。在调用结束时,您可以将其存储到数据库中。这样它将受到保护,不受其他API调用的影响。不需要全球课程。

答案 1 :(得分:-3)

对于全局线程安全类,您应该考虑单例设计模式

public class Logger {
     private static object _lock = new object();
     private static Logger _logger = null;

     public static Instance { get {
          if ( _logger == null ) {
             lock(_lock) {
                 if ( _logger == null ) {
                     _logger = new Logger();
                 }
             }
          }
     }
     private Logger() {}

     public void LogMessage(string message) {
          //code to log here, 
     }
}

还用于记录检出log4net,这是一个功能到达记录器,包括记录到db。