主要担心的是它可能发生在应用程序崩溃的那一刻。如何以安全的方式将xml从多个线程保存到文件中?
答案 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)