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

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

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

Author24 — интернет-сервис помощи студентам
В общем проблема такая. В процедуре создается поток загрузки файла. В этом потоке, после удачной загрузки файла, его имя записывается в 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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.03.2013, 19:14
Ответы с готовыми решениями:

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

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

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

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

2
19 / 19 / 5
Регистрация: 16.09.2012
Сообщений: 80
27.03.2013, 20:22 2
Это можно сделать, и довольно просто, при помощи Task\Task<T>. С BackgroundWorker, вероятно тоже, но здесь я не могу подсказать.
0
0 / 0 / 0
Регистрация: 27.03.2013
Сообщений: 7
27.03.2013, 20:47  [ТС] 3
Тогда подскажи как это реализовать с помощью Task
0
27.03.2013, 20:47
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.03.2013, 20:47
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru