Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
0 / 0 / 0
Регистрация: 27.03.2013
Сообщений: 7

Запись и чтение xml из разных потоков

27.03.2013, 19:14. Показов 2653. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В общем проблема такая. В процедуре создается поток загрузки файла. В этом потоке, после удачной загрузки файла, его имя записывается в xml. Проблема в том, что я не знаю как избавится от ошибки "Файл занят другим процессом".

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
        private void Download(string url)
        {
            BackgroundWorker BW0 = new BackgroundWorker();
            BW0.WorkerSupportsCancellation = true;
            BW0.WorkerReportsProgress = true;
 
            BW0.DoWork += delegate(object sender0, DoWorkEventArgs e0)
            {
                state = DownloadImage(url, ImageAddr, out ImageAddr);
            };
            
            BW0.RunWorkerAsync();
        }
В процедуре DownloadImage происходит загрузка картинки и запись ее имени в XML-файл:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
        public bool DownloadImage(string Url, string OutFilename, out string validfilename)
        {
            // Проверка правильности имени
            string filename = OutFilename.Trim(Path.GetInvalidFileNameChars());
            validfilename = filename;
 
            // Проверки на пустоту
            if (Url == "" || Url == null) return false;
            if (Path.GetDirectoryName(filename) == "" || Path.GetDirectoryName(filename) == null) return false;
            if (Path.GetExtension(Url) == null) return false;
            if (!Directory.Exists(Path.GetDirectoryName(filename))) Directory.CreateDirectory(Path.GetDirectoryName(filename));
            
            long filesize = 0;
            bool state = false;
            long urlsize = -1;
            
            // Если файла нет, загрузить
            if (!File.Exists(filename))
            {
                try
                {
                    urlsize = LoadFile(Url, filename); //процедура загрузки файла, возвращает размер файла
                    FileInfo fi = new FileInfo(filename);
                    filesize = fi.Length;
                    state = (filesize == urlsize);
                }
                catch { return false; }
            }
            else // Если файл есть
            {
                FileInfo fis = new FileInfo(filename);
                filesize = fis.Length;
 
        // В doc содержится список имен файлов в таком формате:
                // <File Name="имя_файла.png" Size="11464" />
        // Проверяем, если загружаемый файл есть в списке, и совпадает его размер
        // возвращаем истину
                if (File.Exists(ImageHashFile))
                {
                    XmlDocument doc = new XmlDocument();
 
                    doc.Load(ImageHashFile); // Здесь бывает ошибка: Файл занят другим процессом
 
                    foreach (XmlNode node in doc.GetElementsByTagName("File"))
                    {
                        string name = node.Attributes["Name"].Value;
                        if (name == Path.GetFileName(filename))
                        {
                            string size = node.Attributes["Size"].Value;
                            urlsize = Convert.ToInt64(size);
 
                            if (filesize == urlsize) return true;
                        }
                    }
 
                }
                
                // Если файла нет, или не совпадают размеры, то загрузить
                try
                {
                    urlsize = LoadFile(Url, filename);
                    FileInfo fi = new FileInfo(filename);
                    filesize = fi.Length;
                    state = (filesize == urlsize);
                }
                catch { return false; }
            }
 
            // Если успех, то записать файл в список
            if (state)
            {
                // Если нет файла то создать
                if (!File.Exists(ImageHashFile))
                {
                    XmlWriter writer = XmlWriter.Create(ImageHashFile);
                    lock (writer)
                    {
                        writer.WriteStartElement("Files");
                        writer.WriteEndElement();
                        writer.Flush();
                        writer.Close();
                    }
                }
 
                XmlDocument doc = new XmlDocument();
 
                doc.Load(ImageHashFile); // Здесь бывает ошибка: Файл занят другим процессом
 
                // Если такой файл есть в списке, то успех
                foreach (XmlNode node in doc.GetElementsByTagName("File"))
                    if (node.Attributes["Name"].Value == Path.GetFileName(filename))
                        return state;
                
        // Если файла нет в списке, то записываем его
                XmlNode element = doc.CreateElement("File");
                doc.DocumentElement.AppendChild(element);
                XmlAttribute attribute = doc.CreateAttribute("Name");
                attribute.Value = Path.GetFileName(filename);
                element.Attributes.Append(attribute);
                XmlAttribute attribute1 = doc.CreateAttribute("Size");
                attribute1.Value = filesize.ToString();
                element.Attributes.Append(attribute1);
                
                doc.Save(ImageHashFile); //Здесь бывает ошибка: Файл занят другим процессом
 
            }
            
            return state;
        }
В итоге, в помеченных местах кода возникают ошибки. Я понимаю, что проблема в том, что запись в файл идет с нескольких потоков одновременно. Нужно синхронизировать потоки, но как это сделать, если потоки анонимны?
Заранее благодарен.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.03.2013, 19:14
Ответы с готовыми решениями:

Чтение и запись в переменную с разных потоков
День добрый! Есть переменная и ведется в нее запись с потока 2,который является не потоком формы. И есть основной поток,который...

Параллельная запись текста в файл из разных потоков
Есть несколько потоков, каждый из них должен записывать информацию в файл. При этом не после закрытия StreawWriter'a, а сразу же. Есть...

Построчная запись в txt файл из разных потоков
Есть 4 потока (threads), мне нужно данные от них записать в тхт файл(построчно). Как это сделать ? Я юзаю File.WriteAllText, но может это...

2
19 / 19 / 5
Регистрация: 16.09.2012
Сообщений: 80
27.03.2013, 20:22
Это можно сделать, и довольно просто, при помощи Task\Task<T>. С BackgroundWorker, вероятно тоже, но здесь я не могу подсказать.
0
0 / 0 / 0
Регистрация: 27.03.2013
Сообщений: 7
27.03.2013, 20:47  [ТС]
Тогда подскажи как это реализовать с помощью Task
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.03.2013, 20:47
Помогаю со студенческими работами здесь

Блокировка потоков на запись и чтение в List<>
Написал примерный код в блокноте (схематичный код - на мелочи не обращаем внимание , думаю суть будет понятна всем что мне требуется) ...

Запись в файл и чтение из него без создания двух потоков
Знаю да есть класс StreamReader и StreamWriter но зачем мне делать 2 потока, мне хочется просто как в С++ открыть 1 обьект на...

Запись и чтение XML
Нужно сохранить в XML файл объект класса CPolygon, через saveFileDialog. Как это можно сделать? private void...

Чтение и запись xml
Здравствуйте. Есть .xml файлик, в котором есть один параметр. &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt; &lt;head&gt; ...

MemoryStream запись и чтение (в разных потоках)
Подскажите как правельно реализовать запись и чтение потока? если делаю так то выдаётся ошибка чтения потока MemoryStream stream; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru