首页 新闻 赞助 找找看

C#多线程下对日志文件操作,出现的异常。

0
悬赏园豆:10 [已解决问题] 解决于 2014-03-13 09:50

  这是一个数据同步程序,运行在数据库服务器上面,将一个数据库中的数据同步到另一个数据库中。对每个表的同步操作,都会添加到各自的日志文件中。现在程序跑起来出现下面的错误。

下面的是示例代码,示例程序中仅仅是一个Form:

问题补充:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace AppTest
{
    public partial class Form1 : Form
    {
        //每隔多长时间执行一次同步操作
        private static readonly int IntervalTime = 10000;

        public Form1()
        {
            InitializeComponent();
            TableSynchro();
        }

        # region 同步数据
        private void TableSynchro()
        {
            //表1
            Tablel1_Thread = new Thread(new ThreadStart(Tablel1_Synchro));
            Tablel1_Thread.Start();
            //表2
            Tablel2_Thread = new Thread(new ThreadStart(Tablel2_Synchro));
            Tablel2_Thread.Start();
            //表3
            Tablel3_Thread = new Thread(new ThreadStart(Tablel3_Synchro));
            Tablel3_Thread.Start();
            //表4
            Tablel4_Thread = new Thread(new ThreadStart(Tablel4_Synchro));
            Tablel4_Thread.Start();
        }

        /*线程同步方法中,通过无限循环和Sleep让线程每隔一段时间执行一次*/
        private Thread Tablel1_Thread;
        private void Tablel1_Synchro()
        {
            while (true)
            {
                string logTxt = "";

                DateTime beginT = DateTime.Now;
                logTxt += "表1:" + "同步操作返结果(略)";
                DateTime endT = DateTime.Now;
                logTxt += "操作时间:" + endT.ToString() + ",用时:" + (endT - beginT).TotalSeconds.ToString() + "" + Environment.NewLine;
                WriteLog(logTxt, "Tablel1");

                Thread.Sleep(IntervalTime);
            }
        }

        private Thread Tablel2_Thread;
        private void Tablel2_Synchro()
        {
            while (true)
            {
                string logTxt = "";

                DateTime beginT = DateTime.Now;
                logTxt += "表2:" + "同步操作返结果(略)";
                DateTime endT = DateTime.Now;
                logTxt += "操作时间:" + endT.ToString() + ",用时:" + (endT - beginT).TotalSeconds.ToString() + "" + Environment.NewLine;
                WriteLog(logTxt, "Tablel2");

                Thread.Sleep(IntervalTime);
            }
        }

        private Thread Tablel3_Thread;
        private void Tablel3_Synchro()
        {
            while (true)
            {
                string logTxt = "";

                DateTime beginT = DateTime.Now;
                logTxt += "表3:" + "同步操作返结果(略)";
                DateTime endT = DateTime.Now;
                logTxt += "操作时间:" + endT.ToString() + ",用时:" + (endT - beginT).TotalSeconds.ToString() + "" + Environment.NewLine;
                WriteLog(logTxt, "Tablel3");

                Thread.Sleep(IntervalTime);
            }
        }

        private Thread Tablel4_Thread;
        private void Tablel4_Synchro()
        {
            while (true)
            {
                string logTxt = "";

                DateTime beginT = DateTime.Now;
                logTxt += "表4:" + "同步操作返结果(略)";
                DateTime endT = DateTime.Now;
                logTxt += "操作时间:" + endT.ToString() + ",用时:" + (endT - beginT).TotalSeconds.ToString() + "" + Environment.NewLine;
                WriteLog(logTxt, "Tablel4");

                Thread.Sleep(IntervalTime);
            }
        }
        #endregion

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="logtxt">增加内容</param>
        /// <param name="fileName">表名用作文件名</param>
        private static void WriteLog(string logtxt, string fileName)
        {
            string directoryPath = Directory.GetCurrentDirectory() + @"\log\";
            string filePath = directoryPath + fileName + ".txt";
            //存放日志文件的目录是否存在
            if (!Directory.Exists(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }

            FileInfo file = new FileInfo(filePath);
            if (!file.Exists)
                file.Create();
            StreamWriter stream = file.AppendText();
            stream.Write(logtxt);
            stream.Flush();
            stream.Close();

        }
    }
}
凡一二三的主页 凡一二三 | 初学一级 | 园豆:85
提问于:2013-05-06 22:13
< >
分享
最佳答案
0

1.LOCK
2.第3方
3.再启个线程,专门负责写日志,所有日志ADD到一个队列中,此线程负责循环写

收获园豆:10
头衔 | 菜鸟二级 |园豆:364 | 2013-05-07 17:33
其他回答(5)
0

几个线程操作同一个文件是不行的,加个锁控制一下

最好使用NLOG这样的现有库或者微软的企业库日志处理

2012 | 园豆:21228 (高人七级) | 2013-05-07 08:41
0

这种资源竞争的情况下,还是lock一下吧,不错log这一块不需要自己写,log4net就现成的。

chenping2008 | 园豆:9836 (大侠五级) | 2013-05-07 09:16
0

推荐使用现有的日志组件。比如log4.net。一定要应用单例模式,

邢少 | 园豆:10926 (专家六级) | 2013-05-07 09:18
0

加锁,或者是用第三方的。

会长 | 园豆:12401 (专家六级) | 2013-05-07 09:22
0

使用线程安全的集合,先将log信息缓存起来,再用其他线程定时输出至log文件,可以解决这个问题.

三阶 | 园豆:1436 (小虾三级) | 2013-05-07 09:55
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册