c#中使用任务工厂的性能问题
本文关键字:性能 问题 工厂 任务 | 更新日期: 2023-09-27 17:50:14
我正在为一个web应用程序编写日志系统,该系统在使用Task.Factory.StartNew(() => iLogEventSave())将其发送到我的日志对象之前记录字典对象中的事件序列。日志记录器似乎工作正常,但在某些情况下,一些事件没有被正确保存,因此我使用lock()语句来纠正这个问题。这样做似乎可以解决问题,但应用程序的性能却因此大幅下降。我怎么能有UI/页面渲染而不必等待任务完成他们的工作?
下面是代码 private static readonly object Locker = new object();
public void iLogEventSave(object state)
{
XmlDocument doc = new XmlDocument();
IDictionary<string, string> EventDetails = (IDictionary<string, string>)state;
string logFile = "";
if(ConfigurationManager.AppSettings["Log_File_Path"].ToString() =="")
{
logFile = HttpRuntime.AppDomainAppPath + "Logs''" + DateTime.Now.ToString("yyyy_MM_dd") + ".txt";
}
else
{
logFile = ConfigurationManager.AppSettings["Log_File_Path"].ToString() + DateTime.Now.ToString("yyyy_MM_dd") + ".txt";
}
lock (Locker)
{
if (File.Exists(logFile))
{
doc.Load(logFile);
}
else
{
var root = doc.CreateElement("Log");
doc.AppendChild(root);
}
var el = (XmlElement)doc.DocumentElement.AppendChild(doc.CreateElement("Event"));
foreach (KeyValuePair<string, string> item in EventDetails)
{
XmlElement Desc = doc.CreateElement("Details");
Desc.SetAttribute(item.Key.ToString(), item.Value);
el.AppendChild(Desc);
}
doc.Save(logFile);
}
}
如果日志在异步执行时没有保存多个事件,则存在未处理的错误。考虑到您正在使用一个文件,我将大胆地说它失败了,因为两个线程正在竞争访问同一个日志文件,第一个获取它的线程锁定了另一个线程。这就是为什么你的锁现在可以工作了,它可以防止其他线程试图抓取文件。
但是记录到一个文件意味着你已经有效地将自己限制在一次一个线程中,并且随着文件的增长处理整个文件。您必须加载越来越多的内容,添加越来越多的内容,并且锁定线程意味着等待记录事件的线程越多,您的开销就越高。所有这些肯定会导致性能下降。
我可以推荐使用数据库表来记录事件吗?文件I/O在资源和时间方面都非常昂贵。通过比较,在这些场景中,数据库的开销更小,吞吐量更好。