【问题标题】:WriteXml not saving a fileWriteXml 不保存文件
【发布时间】:2024-01-23 15:02:01
【问题描述】:

我有一个任务是每 10 秒将我的 DataTable 保存到一个文件中:

void WriteTask(DataTable dt, bool final)
{
    if (final)
    {
       exiting = false;
    }
    while (!exiting)
    {
       lock (users)
       {
          try
          {
             dt.WriteXml(filePath+ "users.xml_be");
             File.Copy(@$"{filePath}users.xml_be", @$"{filePath}users.xml_betemp");
             File.Replace(@$"{filePath}users.xml_betemp", @$"{filePath}users.xml", @$"{filePath}users.xml_be2");
             if (final)
                exiting = true;
             }
             catch (Exception ex)
             {
                try
                {
                   File.AppendAllText($"{filePath}log.txt", $"{DateTime.Now.ToString()} {ex.Message}" + Environment.NewLine);
                   File.AppendAllText($"{filePath}log.txt", $"{ex.StackTrace}" + Environment.NewLine);
                   File.AppendAllText($"{filePath}log.txt", "////////////////////////////////////////////////////////////////" + Environment.NewLine);
                   }
                   catch (Exception)
                   {
                      client.SendMessage(tChannel, ErrorMes1);
                      client.SendMessage(tChannel, $"{ex.Message}|{ex.StackTrace}");
                   }
                }
            }              
            Thread.Sleep(10000);
     }
}

最近我注意到文件没有改变。最奇怪的想法是,当我在记事本++中打开文件时,它说文件已被更改并且它想要重新加载它,但是在我重新加载文件之后,里面没有任何更改。可能是因为文件变得很大吗?它有大约 100 万行。

更新: 因此,我为所有与数据表有关的事情创建了异步任务: 处于无休止循环中的任务,每 30 秒保存一次

async void WriteTask(DataTable dt, bool final)
    {            
        if (final)
        {
            exiting = false;
        }
        while (!exiting)
        {
            Task UvalClockTaksTask = new Task(() => UvalClockTaksAsync());
            Task dbSavingTask = new Task(() => WriteTaskAsync(dt, final));

            Console.WriteLine("start saving");

            UvalClockTaksTask.Start(); 
            await UvalClockTaksTask;

            dbSavingTask.Start();
            await dbSavingTask;   
            
            Console.WriteLine("saved");
            Thread.Sleep(30000);
        }
    }

这里我正在为 dt 中的每个用户更新时间戳

void UvalClockTaksAsync()
    {
        foreach (DataRow row in users.Rows)
        {
            if (Convert.ToDouble(row[uvaltimePost]) < TimeCurrent)
                row[uvaltimePost] = TimeCurrent;
        }
    }

我在这里进行保存

void WriteTaskAsync(DataTable dt, bool final)
    {
            try
            {
                dt.WriteXml(filePath + "users.xml_be");                    
                File.Replace(@$"{filePath}users.xml_be", @$"{filePath}users.xml", @$"{filePath}users.xml_be2");
                if (final)
                    exiting = true;
            }
            catch (Exception ex)
            {
                try
                {
                    File.AppendAllText($"{filePath}log.txt", $"{DateTime.Now.ToString()} {ex.Message}" + Environment.NewLine);
                    File.AppendAllText($"{filePath}log.txt", $"{ex.StackTrace}" + Environment.NewLine);
                    File.AppendAllText($"{filePath}log.txt", "////////////////////////////////////////////////////////////////" + Environment.NewLine);
                }
                catch (Exception)
                {
                    client.SendMessage(tChannel, ErrorMes1);
                    client.SendMessage(tChannel, $"{ex.Message}|{ex.StackTrace}");
                }
            }            
    }

它仍然不是每次都保存,最奇怪的是文件 users.xml 和 users.xml_be 不一样!用户时间戳总是相差 10 秒。我是说wtf

【问题讨论】:

  • 您确定数据表在写入之间发生变化吗?如果内容相同,文件将被更新(Notepad++ 会通知您),但您不会看到任何更改,因为没有任何更改。
  • 而不是试图睡觉并希望文件被完全写入。您可以创建一个异步方法(比如“WriteDataTableAsync”)来写入文件。并在主要方法中等待 WriteDataTableAsync。这将始终确保将数据很好地写入文件。 aync msdn help

标签: c# datatable


【解决方案1】:

如果文件有大量数据,写入物理路径可能需要一些时间。那么能不能增加时间线(Thread.Sleep(10000);)

【讨论】:

  • 行为没有改变,有时它保存,有时没有。我认为 25mb 文件的保存时间不会超过 10 秒