c# - 使用这种异步日志记录代码有什么缺点?

标签 c# postsharp task-parallel-library multithreading

我刚刚编写的一些代码如下。

它演示了将 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/

相关文章:

c# - 你能为 console.ReadLIne() 设置一个变量吗?

c# - 寻找Postsharp老挝的好教程/文档,了解 "Librarian"样本

c#-4.0 - Postsharp - 将 OnMethodBoundaryAspect 添加到抽象方法 - 方面未触发

c# - 通过多线程调用静态方法 - 它们可以干扰彼此的输入参数吗

正则表达式选择 { 和 } 之间的所有输入

c# - ConcurrentBag<T> 实现中是否存在内存泄漏?

c# - 使用通过私有(private)构造函数返回新实例的静态方法有优势吗?

c# - 是否可以使用无锁(等待)双向链表?

c# - 在字典中添加新项目或更新现有项目的方法

wpf - 使用 PostSharp 为嵌套属性或集合撤消重做