我刚刚编写的一些代码如下。
它演示了将 PostSharp 方面应用于方法,以便以异步方式记录方法调用的持续时间 - 这样,如果日志记录过程很慢,则装饰方法的调用者不会看到这种性能损失与方面。
它似乎可以工作,MyFirstMethod 已完成,日志记录方法在单独的线程中启动,MySecondMethod 并行运行。这个想法是,使用类似的工具来装饰高流量 Web 应用程序(即高度多线程环境)中的方法。
这样做有哪些陷阱? (例如,我担心在任何给定时间达到允许的线程数限制)。
using System;
using System.Threading.Tasks;
using NUnit.Framework;
using PostSharp.Aspects;
namespace Test
{
[TestFixture]
public class TestClass
{
[Test]
public void MyTest()
{
MyFirstMethod();
MySecondMethod();
}
[PerformanceInstrument]
private void MyFirstMethod()
{
//do nothing
}
private void MySecondMethod()
{
for (int x = 0; x < 9999999; x++);
}
}
[Serializable]
public class PerformanceInstrument : MethodInterceptionAspect
{
public override void OnInvoke(MethodInterceptionArgs args)
{
var startDtg = DateTime.Now;
args.Proceed();
var duration = DateTime.Now - startDtg;
Task.Factory.StartNew(() => MyLogger.MyLoggingMethod(duration)); //invoke the logging method asynchronously
}
}
public static class MyLogger
{
public static void MyLoggingMethod(TimeSpan duration)
{
for (int x = 0; x < 9999999; x++);
Console.WriteLine(duration);
}
}
}
最佳答案
我在这里看到的唯一可能的缺点是管理任务的开销,我确信这可能微不足道,但我还没有深入研究 TPL 内容来确定。
我在大型 Web 应用程序中使用的另一种方法是让日志记录将日志消息记录写入内存列表,然后我有一个后台线程负责在后台写入日志消息。目前,该解决方案让线程经常检查列表,如果列表长度超过特定阈值或列表没有刷新超过特定时间,则将列表刷新到磁盘(在我们的示例数据库中),这永远是第一位的。
这类似于生产者/消费者模式,您在其中编写代码生成日志消息,而消费者负责将这些消息刷新到持久性介质。
关于c# - 使用这种异步日志记录代码有什么缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3219042/