TextWriter не пишет все файлы - PullRequest
2 голосов
/ 25 января 2011

Я написал службу, в которой запущен отдельный поток, который считывает примерно 400 записей из базы данных и сериализует их в файлы XML. Он работает нормально, ошибок нет, и он сообщает, что все файлы были правильно экспортированы, однако впоследствии появляется только несколько файлов xml, и каждый раз их число всегда меняется. Я проверил, не вызывает ли это определенную запись проблем, но все они хорошо читаются и, кажется, пишут плавно, но не ...

После воспроизведения и установки задержки в 250 мс между каждой записью все они экспортируются должным образом, поэтому я предполагаю, что это должно быть как-то связано с записью такого количества файлов в такой быстрой последовательности, но я не знаю, почему мог бы подумать, что сообщит о какой-то ошибке, если не напишет правильно, но ничего нет.

Вот код для тех, кто хочет попробовать:

static void Main(string[] args)
{
    ExportTestData();
}

public static void ExportTestData()
{
    List<TestObject> testObjs = GetData();

    foreach (TestObject obj in testObjs)
    {
        ExportObj(obj);
        //Thread.Sleep(10);
    }
}

public static List<TestObject> GetData()
{
    List<TestObject> result = new List<TestObject>();

    for (int i = 0; i < 500; i++)
    {
        result.Add(new TestObject()
        {
            Date = DateTime.Now.AddDays(-1),
            AnotherDate = DateTime.Now.AddDays(-2),
            AnotherAnotherDate = DateTime.Now,
            DoubleOne = 1.0,
            DoubleTwo = 2.0,
            DoubleThree = 3.0,
            Number = 345,
            SomeCode = "blah",
            SomeId = "wobble wobble"
        });
    }

    return result;
}

public static void ExportObj(TestObject obj)
{
    try
    {
        string path = Path.Combine(@"C:\temp\exports", String.Format("{0}-{1}{2}", DateTime.Now.ToString("yyyyMMdd"), String.Format("{0:HHmmssfff}", DateTime.Now), ".xml"));
        SerializeTo(obj, path);
    }
    catch (Exception ex)
    {

    }
}

public static bool SerializeTo<T>(T obj, string path)
{
    XmlSerializer xs = new XmlSerializer(obj.GetType());
    using (TextWriter writer = new StreamWriter(path, false))
    {
        xs.Serialize(writer, obj);
    }
    return true;
}

Попробуйте комментировать \ раскомментировать Thread.Sleep (10), чтобы увидеть проблему

Кто-нибудь знает, почему он это делает? А можете подсказать, как мне избежать этой проблемы?

Спасибо

РЕДАКТИРОВАТЬ: Решено. Имя файла, основанное на времени, не было достаточно уникальным и переписывало ранее записанные файлы. Должен был заметить это раньше, спасибо за вашу помощь

Ответы [ 5 ]

1 голос
/ 25 января 2011

Хорошо, я обнаружил проблему, я использовал временное имя файла, которое, как мне казалось, было бы достаточно уникальным для каждого файла, оказалось, что они работают с одинаковыми именами и перезаписывают друг друга.

Если я изменю его на использование уникальных имен файлов, это сработает! Спасибо за вашу помощь

1 голос
/ 25 января 2011

Возможно, попробуйте поместить writer в блок использования для немедленной утилизации?Что-то вроде

XmlSerializer xs = new XmlSerializer(obj.GetType());
using(TextWriter writer = new StreamWriter(path, false)) 
{
    xs.Serialize(writer, obj);
}
0 голосов
/ 25 января 2011

Многопоточность может вызвать эту проблему. Задержка в 250 мс является доказательством этого.

У вас есть несколько потоков, делающих это?

0 голосов
/ 25 января 2011

Если вы не получаете никаких исключений, то операторы использования, предложенные другими ответами, не помогут - хотя вы должны изменить их на использование в любом случае. В этот момент вам больше не нужен закрытый звонок:

XmlSerializer xs = new XmlSerializer(obj.GetType());
using(TextWriter writer = new StreamWriter(path, false))
{
    xs.Serialize(writer, obj);
}

Однако я не думаю, что проблема заключается в этом коде. Я подозреваю, что это что-то как проблема "захвата переменной цикла в лямбда-выражении", которая возникает так часто. Если вам удастся создать короткую, но завершенную программу, которая демонстрирует проблему, диагностику будет намного проще.

Я предлагаю вам создать простое консольное приложение, которое пытается создать, скажем, 5000 файлов, сериализующих некоторый простой объект. Посмотрим, сможешь ли ты так же потерпеть неудачу.

0 голосов
/ 25 января 2011

Утилизируйте писателя

public static bool SerializeTo<T>(T obj, string path)
{
    XmlSerializer xs = new XmlSerializer(obj.GetType());
    using(TextWriter writer = new StreamWriter(path, false)) {
        xs.Serialize(writer, obj);
        writer.Close();
    }
    return true;
}
...