简体   繁体   English

无法使用线程和XDocument写入XML文件

[英]Unable to write to XML file using threads and XDocument

string filepath = Environment.CurrentDirectory + @"Expense.xml";

public void  WriteToXML(object param)
{
Expense exp = (Expense)param;
   if (File.Exists(filepath)) {
    XDocument xDocument = XDocument.Load(filepath);

    XElement root = xDocument.Element("Expenses");
    IEnumerable<XElement> rows = root.Descendants("Expense");
    XElement firstRow = rows.First();

    firstRow.AddBeforeSelf(new XElement("Expense",
           new XElement("Id", exp.Id.ToString()),
           new XElement("Amount", exp.Amount.ToString()),
           new XElement("Contact", exp.Contact),
           new XElement("Description", exp.Description),
           new XElement("Datetime", exp.Datetime)));
    xDocument.Save(filepath);
 }
}

Expense exp = new Expense();
exp.Id = new Random().Next(1, 10000);
exp.Amount = float.Parse(text1[count].Text);
exp.Contact = combo1[count].SelectedItem.ToString();
exp.Description = rtext1[count].Text.ToString();
exp.Datetime = DateTime.Now.ToString("MM-dd-yyyy");

workerThread = new Thread(newParameterizedThreadStart(WriteToXML));
workerThread.Start(exp); // throws System.IO.IOException

I'm unable to write to XML file with worker treads - I'm getting this error: 我无法使用辅助程序写入XML文件-我收到此错误:

System.IO.IOException: 'The process cannot access the file 'C:\\work\\FinanceManagement\\FinanceManagement\\bin\\DebugExpense.xml' because it is being used by another process. System.IO.IOException:'该进程无法访问文件'C:\\ work \\ FinanceManagement \\ FinanceManagement \\ bin \\ DebugExpense.xml',因为该文件正在被另一个进程使用。

but if I use it like WriteToXML(exp); 但是如果我像WriteToXML(exp);一样使用它WriteToXML(exp); it works. 有用。 I think XDocument.Load(filepath) is not thread safe. 我认为XDocument.Load(filepath)不是线程安全的。 How can I resolve this issue? 我该如何解决这个问题?

Try introducting a lock , see if it resolves the issue: 尝试引入lock ,看看它是否可以解决问题:

// Declare this somewhere in your project, can be in same class as WriteToXML
static object XmlLocker;

Then wrap a lock around the logic: 然后在逻辑周围包裹一个lock

public void WriteToXML(object param)
{
    Expense exp = (Expense)param;

    lock (XmlLocker) // <-- this limits one thread at a time
    {
        if (File.Exists(filepath))
        {
            XDocument xDocument = XDocument.Load(filepath);

            XElement root = xDocument.Element("Expenses");
            IEnumerable<XElement> rows = root.Descendants("Expense");
            XElement firstRow = rows.First();

            firstRow.AddBeforeSelf(new XElement("Expense",
                   new XElement("Id", exp.Id.ToString()),
                   new XElement("Amount", exp.Amount.ToString()),
                   new XElement("Contact", exp.Contact),
                   new XElement("Description", exp.Description),
                   new XElement("Datetime", exp.Datetime)));
            xDocument.Save(filepath);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM