我正在使用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();
答案 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。