通过网上一个多线程写入日志的方法改造,插入数据时,对数据库中一个string类型的字段值进行++ 如果有更好的方法,还请留言,不用数据库自增

using NFF.Bussiness.Interface;
using NFF.EF.Model;
using NFF.Framework.Core.IOC;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Unity;

namespace LogWrite.LogHelper
{
public class LogHandler
{

    // 用于存放写日志任务的队列
    private Queue<Action> _queue;

    // 用于写日志的线程
    private Thread _loggingThread;

    // 用于通知是否有新日志要写的“信号器”
    private ManualResetEvent _hasNew;


    static INF_TestService testService = null;
    // 构造函数,初始化。
    private LogHandler()
    {

        IUnityContainer container = DIFactory.GetContainer();
        testService = container.Resolve<INF_TestService>();

        _queue = new Queue<Action>();
        _hasNew = new ManualResetEvent(false);

        _loggingThread = new Thread(Process);
        _loggingThread.IsBackground = true;
        _loggingThread.Start();
    }

    // 使用单例模式,保持一个Logger对象
    private static readonly LogHandler _logger = new LogHandler();
    private static LogHandler GetInstance()
    {
        /* 不安全代码
        lock (locker) {
            if (_logger == null) {
                _logger = new Logger();
            }
        }*/
        return _logger;
    }

    // 处理队列中的任务
    private void Process()
    {
        while (true)
        {
            // 等待接收信号,阻塞线程。
            _hasNew.WaitOne();

            // 接收到信号后,重置“信号器”,信号关闭。
            _hasNew.Reset();

            // 由于队列中的任务可能在极速地增加,这里等待是为了一次能处理更多的任务,减少对队列的频繁“进出”操作。
            Thread.Sleep(100);

            // 开始执行队列中的任务。
            // 由于执行过程中还可能会有新的任务,所以不能直接对原来的 _queue 进行操作,
            // 先将_queue中的任务复制一份后将其清空,然后对这份拷贝进行操作。

            Queue<Action> queueCopy;
            lock (_queue)
            {
                queueCopy = new Queue<Action>(_queue);
                _queue.Clear();
            }

            foreach (var action in queueCopy)
            {
                action();
            }
        }
    }

    private void Insert(Model_Tes model)
    {
        lock (_queue)
        { // todo: 这里存在线程安全问题,可能会发生阻塞。
          // 将任务加到队列

            _queue.Enqueue(() =>
            {
                var result = testService.GetCount();
                model.Age = (result++).ToString();
                testService.InsertNFFTest(model);
            });
        }

        // 打开“信号”
        _hasNew.Set();
    }

    // 公开一个Write方法供外部调用
    public static void insertNFTest(Model_Test model)
    {
        // WriteLog 方法只是向队列中添加任务,执行时间极短,所以使用Task.Run。
        Task.Run(() => GetInstance().Insert(model));
    }
}

}

前台模拟并发处理

        TaskFactory taskFactory = new TaskFactory();

        for (int i = 0; i < 10000; i++)//并发
        {
            taskFactory.StartNew(() =>
            {
                NF_Test model = new NF_Test();
                LogHandler.insertNFTest(model);
            });
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值