2011-01-25 2 views
2

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

После игры и задержки в 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), чтобы увидеть проблему

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

Благодаря

EDIT: решаемая. Имя файла, основанного на времени, не было достаточно уникальным и перезаписывало ранее записанные файлы. Должен был заметить это раньше, спасибо за помощь.

+0

Откуда вы получаете «путь»? –

+0

@Lasse Path прошел через уникальный путь к файлу для каждого файла. – w69rdy

ответ

1

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

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

+0

Найдено 1 минуту назад. В следующий раз создайте Unit Tests перед реализацией функции. :) –

1

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

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

. Если вы вызываете Dispose (через оператор using), вам не нужен вызов Close. –

+0

Что объясняет это поведение? Я не понимаю, почему бы не избавить писателя от его проблемы. Вы можете объяснить, пожалуйста ? – Shimrod

+0

Спасибо, Джон, обновлено :) – Tom

0

Утилизировать писатель

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; 
} 
+0

Почему бы не написать.Dispose(); // после writer.Close(); – Pratik

0

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

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

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

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

+0

Спасибо, Джон, я принял ваш совет и воссоздал проблему в тестовом приложении. Я обновил свой вопрос, включив ссылку для его загрузки. – w69rdy

+0

@ w69rdy: Это боль, чтобы загрузить его из другого места ... насколько он велик? Я ожидаю, что это будет легко до 100 строк - вы должны включить его в вопрос. –

+0

Хороший вопрос, поэтому я включил его в вопрос сейчас. Когда я убрал его, стало немного понятнее, почему он не работает, получается, что мой способ генерации уникальных имен файлов действительно не такой умный. – w69rdy

0

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

Есть ли у вас несколько потоков?

+0

Я делаю одновременно работают другие потоки, но я пробовал это, и это не имеет никакого значения. Я включил тестовое приложение в свои вопросы сейчас, если вы хотите увидеть проблему в действии. – w69rdy

Смежные вопросы