当调用可以来自多个线程时,保存xml文件的安全方法

时间:2011-11-02 05:10:26

标签: c# .net

主要担心的是它可能发生在应用程序崩溃的那一刻。如何以安全的方式将xml从多个线程保存到文件中?

4 个答案:

答案 0 :(得分:3)

保存到多个文件。如果您正在尝试保存用于验尸的信息,您希望尽可能简单。在最好的情况下,同时保存到单个XML文件是困难的;这是你想要做的最后一件事,因为你的程序喘息着它的最后一口气。

答案 1 :(得分:2)

和平常一样。如果您有一个高效,快速且线程安全的方法来导出到XML,则可以在主异常处理程序中调用它。你需要注意不要做不必要的工作,因为你冒险抛出另一个例外。

如果您没有线程安全方法,您只需要像往常一样解决(线程安全框架方法,同步等)

如果应用程序非常重要,您可以采取各种预防措施(与线程无关),例如在磁盘空间不足的情况下保留所需大小的文件。

答案 2 :(得分:1)

我在从多个线程写入日志文件时遇到了这样的问题 我所做的是创建一个队列来保存数据,而不是写入文件和 每个写命令都调用一个add to queue命令,我也使队列线程安全

每次从队列中挑选文本并将文本追加到文件

时都有内部流程

这是我的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AC.ChatServer.Classes
{
    public delegate void OnDataAddedHandler(string data);
    public class LogManager
    {
        #region Fields
        private System.Threading.Mutex logMutex;
        private string filePath;
        private static LogManager instance;
        private AndcQ q;
        #endregion


        #region Property
        public void Initiate()
        {
        }
        public static LogManager Instance
        {
            get
            {
                if (instance == null)
                    instance = new LogManager();
                return instance;
            }
        }
        #endregion

        #region Helper function
        public void AddtOlog(string data)
        {
            q.Enqueue(data);
        }
        #endregion

        #region Constructor
        private LogManager()
        {

            q = new AndcQ(100);
            filePath = System.Configuration.ConfigurationManager.AppSettings["LogFileFolder"];
            logMutex = new System.Threading.Mutex();
            q.DataAdded += new OnDataAddedHandler(q_DataAdded);

        }
        private string GetFileName()
        {
            string fileName = DateTime.Today.ToString("_yyyyMMdd");
            return string.Format(@"{0}\{1}.txt", filePath, fileName);
        }
        private void WriteToFile(object data)
        {

            string fileName = GetFileName();
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fileName, true, Encoding.UTF8))
            {
                sw.WriteLine(data.ToString());
            }
        }
        private delegate void WriteToFileCallBack(string data);
        void q_DataAdded(string data)
        {
            logMutex.WaitOne();
            WriteToFileCallBack caller = new WriteToFileCallBack(WriteToFile);
            IAsyncResult r = caller.BeginInvoke(data, null, null);
            caller.EndInvoke(r);
            logMutex.ReleaseMutex();
        }
        #endregion
    }
    public class AndcQ : System.Collections.Queue
    {
        #region Events
        public event OnDataAddedHandler DataAdded;
        #endregion


        public AndcQ(int capacity)
            : base(capacity)
        {

        }
        public AndcQ()
            : base()
        {

        }
        public new void Enqueue(object obj)
        {

            base.Enqueue(obj);
            if (DataAdded != null)
                lock (this)
                {
                    if (this.Count > 0)
                    {
                        DataAdded(this.Dequeue().ToString());
                    }
                }
        }
    }
}

答案 3 :(得分:0)

在Vista及以上版本中有可用的事务性NTFS

Atomic file copy under .NET

Atomicity of File.Move

Atomic file copy VB.Net