异常问题记录:

本想自己手动实现一个日志记录功能。使用Queue队列集合来实现多线程的日志记录。

测试 一个线程写入数据Enqueue和一个线程读取数据Dequeue ,直接用的无休眠死循环。

终于抛出异常:源数组长度不足。请检查 srcIndex 和长度以及数组的下限。

于是百度之。百度结果 说是多线程写入数据 需要锁定操作lock。

尝试后无效果   依然报异常。

最后解决办法  是 在 Queue 读和 都加上锁定。测试N多线程同时写入和读错都能正常。

LogModel类

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI; namespace Common.Helper.LogHelper
{
/// <summary>
/// 日志模型
/// </summary>
public class LogModel
{
/// <summary>
/// 日志要存的路径 默认路径:网站根目录 + Log 文件夹
/// </summary>
public string logFilePath = HttpContext.Current.Server.MapPath("~/") + @"\Log\"; private string _logFileName; /// <summary>
/// 日志文件名字
/// </summary>
public string logFileName
{
get { return _logFileName + "_" + DateTime.Now.ToString("yyyyMMdd"); }
set { _logFileName = value; }
} private string _logMessg; /// <summary>
/// 日志内容
/// </summary>
public string logMessg
{
get
{
return "====begin====================" + DateTime.Now.ToString() + "====Queue.Count:" + LogHelper.LogQueue.Count + "====================\r\n\r\n"
+ _logMessg
+ "\r\n\r\n====end====================" + DateTime.Now.ToString() + "====Queue.Count:" + LogHelper.LogQueue.Count + "===================="
+ "\r\n\r\n\r\n";
}
set { _logMessg = value; }
}
}
}

LogHelper类

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace Common.Helper.LogHelper
{
/// <summary>
/// 日志操作辅助类
/// zhaopeiym@163.com
/// 创建20150104 修改20150104
/// </summary>
public class LogHelper
{
/// <summary>
/// 消息队列
/// </summary>
private static Queue<LogModel> logQueue = new Queue<LogModel>();
/// <summary>
/// 消息队列 对外只读
/// </summary>
public static Queue<LogModel> LogQueue
{
get { return LogHelper.logQueue; }
} /// <summary>
/// 标志锁
/// </summary>
static string myLock = "true"; /// <summary>
/// 写入日志文件
/// </summary>
/// <param name="logmede"></param>
public static void logWrite(LogModel logmede)
{
// 这里需要锁上 不然会出现:源数组长度不足。请检查 srcIndex 和长度以及数组的下限。异常
//网上有资料说 http://blog.csdn.net/greatbody/article/details/26135057 不能多线程同时写入队列
//其实 不仅仅 不能同时写入队列 也不能同时读和写如队列 所以 在Dequeue 取的时候也要锁定一个对象
lock (myLock)
logQueue.Enqueue(logmede);
logStartWrite();
} /// <summary>
/// 部分日志文件大小
/// </summary>
public static int SectionlogFileSize = * * ; // 1024Byte * 1024KB * 1MB /// <summary>
/// 变动文件大小
/// </summary>
public static int fileSize = * * ; /// <summary>
/// 文件编码格式
/// </summary>
public static Encoding encoding = Encoding.Default; /// <summary>
/// 是否开始自动记录日志
/// </summary>
private static bool isStart = false; /// <summary>
/// 开始把队列消息写入文件
/// </summary>
private static void logStartWrite()
{
if (isStart)
return;
isStart = true;
Thread t = new Thread(delegate()
{
while (true)
{
if (LogHelper.logQueue.Count >= )
{
LogModel m = null;
lock (myLock)
m = LogHelper.logQueue.Dequeue();
if (m == null)
continue;
if (!Directory.Exists(m.logFilePath))
Directory.CreateDirectory(m.logFilePath); int i = ;
//部分 日志 文件路径
string SectionfileFullName = m.logFilePath + m.logFileName + "_" + i.ToString("") + ".txt";
//最新的写了内容的 部分 日志文件路径
string TopSectionfileFullName = SectionfileFullName;
// 需要实时更新的 最新日志文件 路径
string LogfileFullNqme = m.logFilePath + m.logFileName + ".txt"; FileInfo file = new FileInfo(SectionfileFullName);
while (file.Exists && file.Length >= LogHelper.SectionlogFileSize)
{
TopSectionfileFullName = SectionfileFullName;
i++;
SectionfileFullName = m.logFilePath + m.logFileName + "_" + i.ToString("") + ".txt";
file = new FileInfo(SectionfileFullName);
} try
{
if (!file.Exists)//如果不存在 这个文件 就说明需要 创建新的部分日志文件了
{
//因为SectionfileFullName路径的文件不存在 所以创建
File.WriteAllText(SectionfileFullName, m.logMessg, encoding); FileInfo Logfile = new FileInfo(LogfileFullNqme);
if (Logfile.Exists && Logfile.Length >= LogHelper.fileSize)
//先清空 然后加上 上一个部分文件的内容
File.WriteAllText(LogfileFullNqme, File.ReadAllText(TopSectionfileFullName, encoding), encoding);//如果存在则覆盖
}
else
File.AppendAllText(SectionfileFullName, m.logMessg, encoding);//累加 //追加这次内容 到动态更新的日志文件
File.AppendAllText(LogfileFullNqme, m.logMessg, encoding);
}
catch (Exception ex)
{
throw ex;
} }
else
{
isStart = false;//标记下次可执行
break;//跳出循环
}
}
});
t.Start();
}
}
}

Queue插入的时候报错:源数组长度不足。请检查 srcIndex 和长度以及数组的下限。的更多相关文章

  1. 记录Queue插入的时候报错

    Queue 队列  特性  先进先出     和栈 Stack  非常相似 不过 栈 遵循 后进先出 Queue 和Stack 都存在数据并发的 问题 public static Queue<P ...

  2. vscode源代码管理(vscode报错 未找到Git,请安装Git,或在"git.path" 设置中配置)

    vscode源代码管理(vscode报错 未找到Git,请安装Git,或在"git.path" 设置中配置) 直接上图,电脑上已经安装git,由于vscode没有找到git,所以v ...

  3. System.ArgumentException: 目标数组的长度不够。请检查 destIndex 和长度以及数组的下限

    扫码支付接口将要上线,近几天在优化系统性能.昨天把日志Helper类的日志记录改成了使用Queue<T>对象来实现异步处理.做了单元测试,并模拟多线程来测试后,发现正常.今天将站点部署到准 ...

  4. 小记:目标数组的长度不够。请检查 destIndex 和长度以及数组的下限。

    异常:System.ArgumentException: 目标数组的长度不够.请检查 destIndex 和长度以及数组的下限.(不好意思忘记截图了) 发生异常的代码如下: var list = ne ...

  5. MYSQL timestamp NOT NULL插入NULL的报错问题

    1. 在开发两个数据库数据同步功能的时候,需要在本地搭建一个本地的数据库作为一个本地库,然后用于同步开发库中的数据.在插入的时候出现了一个问题. 问题描述: 我们每张表中都会存在一个create_ti ...

  6. Oracle 插入时间时 报错:ORA-01861: 文字与格式字符串不匹配 的解决办法

    一.写sql的方式插入到Oracle中 往oracle中插入时间  '2007-12-28 10:07:24'如果直接按照字符串方式,或者,直接使用to_date('2007-12-28 10:07: ...

  7. 插入mysql语句报错:1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near

    插入一个很简单的sql语句时候,mysql一直报错: [SQL] INSERT INTO ORDER ( id, activity_id, order_type, phone, order_amoun ...

  8. MySql数据库插入或更新报错:Cannot add or update a child row: a foreign key constraint fails

    具体报错信息: Cannot add or update a child row: a foreign key constraint fails (`xxx`.`AAA`, CONSTRAINT `t ...

  9. php里面为什么header之前有输出报错 源码分析

    众所周知,php 里面 header之前有输出的话,会报错,例如下面这样   就这个错误,我们开始查阅php源代码,到底是怎样做的,至于php源代码分析,安装,和调试时怎样配置的,我会专门写一篇文章去 ...

随机推荐

  1. CSS盒子模型学习记录2

    参考:http://www.blueidea.com/tech/web/2007/4545_2.asp 代码试验: html代码: <!DOCTYPE html PUBLIC "-// ...

  2. 交换两个数-c++实现

    今天看了下交换数值的小程序,网上挺多的,整理了下,,因为参考较多,没一一给出链接,若原作者看到,可以留言,我会添加 // example_1_6_function_swap.cpp : 定义控制台应用 ...

  3. framebuffer应用编程实践

    framebuffer的使用主要包括4个部分: (1):首先需要打开设备文件 /dev/fb0. (2):获取设备的信息.包括可变信息和不可变信息,分别使用两个结构体来进行封装,这两个结构体在 < ...

  4. hdu 3667 拆边加最小费用流

    Transportation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  5. matlab squeeze函数的用法

    matlab中squeeze函数用于删除矩阵中的单一维(Remove singleton dimensions),比如执行下面的代码,随机产生一个1x2x3的矩阵A,然后squeeze(A)将返回一个 ...

  6. diocp_tcp_client单元源码与注释

    (* * Unit owner: d10.天地弦 * blog: http://www.cnblogs.com/dksoft * homePage: www.diocp.org * * 2015-02 ...

  7. centos 7 u盘安装

    centos 7 u盘安装 http://www.centoscn.com/image-text/setup/2014/0724/3342.html

  8. [转载] 4. JebAPI 之 jeb.api.ui

    本文转载自: https://www.zybuluo.com/oro-oro/note/145250 JebInstance可以通过getUI()方法来获得jeb.api.ui.JebUI. JebU ...

  9. php 正则获取html属性值

    个人不会写正则,但是工作中遇到了又没办法,所以记录下以后再遇到就好找了,呵呵 言归正传,下面是用正则匹配img的属性的方法: 1.匹配 “img” 中的 “src” 属性 $str='<img ...

  10. hdu 3254 (状压DP) Corn Fields

    poj 3254 n乘m的矩阵,1表示这块区域可以放牛,0,表示不能,而且不能在相邻的(包括上下相邻)两个区域放牛,问有多少种放牛的方法,全部不放也是一种方法. 对于每块可以放牛的区域,有放或者不放两 ...