Bonjour à tous, je rencontre un problème que je ne comprend pas avec un code. En effet, je souhaite télécharger une liste de fichier sur internet et mettre à jour un datagridview en fonction du résultat du téléchargement.
Pour effectuer le téléchargement, j'utilise un array qui stocke les thread et je mets à jour suivant des événements sur le téléchargement.
Voici le code de la classe filedownloader:
et la partie du code que j'utilise pour la mise à jour de l'interface et les téléchargements
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123 using System; using System.IO; using System.Net; namespace FileDownloader { public class FileDownloader { public event _delDownloadStarting DownloadStarting; public event _delDownloadCompleted DownloadCompleted; public delegate void _delDownloadStarting(FileDownloader thread); public delegate void _delDownloadCompleted(FileDownloader thread, bool isSuccess); private string _DocumentUrl = string.Empty; private string _DirectoryPath = string.Empty; private int _timeoutrequest; public bool _IsDownloading = false; public bool _IsDownloadSuccessful = false; private bool _IsStarted = false; public bool _isDownloaded = false; public int RowIndex; public bool IsStarted { get{return _IsStarted;} } private FileDownloader() {} public FileDownloader(string documentUrl, string directory, int timeoutrequest = 5000) { _DocumentUrl = documentUrl; _DirectoryPath = directory; _timeoutrequest = timeoutrequest; } public string FileName { get { if (_DocumentUrl.Equals(string.Empty)) throw new ArgumentException("Please supply a document url."); int loc = _DocumentUrl.LastIndexOf("/") + 1; int len = _DocumentUrl.Length - loc; string filename = _DocumentUrl.Substring(loc, len); return filename; } } private void IsValid() { if (_DocumentUrl.Equals(string.Empty)) throw new ArgumentException("Please supply a document url."); if (_DirectoryPath.Equals(string.Empty)) throw new ArgumentException("Please supply a directory."); } public void StartDownload() { IsValid(); _IsStarted = true; //TODO: ne passe pas _isStared à true ???????? DownloadStarting(this); //raise the download starting event _IsDownloading = true; Stream stream = null; FileStream fstream = null; try { string destFileName = _DirectoryPath + "\\" + FileName; destFileName = destFileName.Replace("/", " ").Replace("%20", " "); if (File.Exists(destFileName) == false) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_DocumentUrl); request.Timeout = _timeoutrequest; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); stream = response.GetResponseStream(); //TODO: quid si redirigé???? byte[] inBuffer = ReadFully(stream, 32768); fstream = new FileStream(destFileName, FileMode.OpenOrCreate, FileAccess.Write); fstream.Write(inBuffer, 0, inBuffer.Length); fstream.Close(); stream.Close(); } _IsDownloadSuccessful = true; _IsDownloading = false; _isDownloaded = true; } catch(Exception ex) { _IsDownloadSuccessful = false; _isDownloaded = false; } finally { if (fstream != null) fstream.Close(); if (stream != null) stream.Close(); DownloadCompleted(this, _IsDownloadSuccessful); } } public byte[] ReadFully(Stream stream, int initialLength) { //Code qui fonctionne ..... } } }
Le problème se trouve en faite dans la partie SetStatus. je ne parvient pas à intercepter le cas d'une erreur. le mode pas à pas montre que IsSatrted est toujours à false. Comme si la ligne 71 de la class FileDownloader n'était pas prise en compte avant le déclenchement de l’événement DownloadStarting(this).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 using System; using System.Drawing; using System.Collections; using System.Collections.Generic; using System.Windows.Forms; using System.Threading; namespace FileDownloader.Gui { public partial class Download : UserControl { private const Int16 CELLCOLOR = 0; private const Int16 CELLHREF = 1; private const Int16 CELLSTATUS = 2; private string[] _listfilesTypes = new string[] private FileCtrlr _ctrl = new FileCtrlr(); private ArrayList _threads = new ArrayList(); private ArrayList _instances = new ArrayList(); private int _activeDownloadCount = 0; private object _lockObject = new object(); public Download() { InitializeComponent(); CreateHeader(); lstBxFiltres.Items.AddRange(_listfilesTypes); btTelecharger.Enabled = false; btAnnuler.Enabled = false; } private void Telechargement(string dir) { // TODO: attention à partir de là interdit de réorganiser le datagrid: téléchargera les bon fichier mais n'adaptera pas la bonne ligne pour les info... CreateThreadArray(dtgvListFiles.SelectedRows,dir); dtgvListFiles.ClearSelection(); StartDownload(); } private void CreateThreadArray(DataGridViewSelectedRowCollection col, string dir) { FileDownloader download = null; Mark m = null; foreach (DataGridViewRow row in col) { m = row.Cells[CELLHREF].Tag as Mark; row.Cells[CELLSTATUS].Value = "En attente"; download = new FileDownloader(m.Href, dir); download.RowIndex = row.Index; row.Cells[CELLCOLOR].Tag = download; try { ThreadStart tsDelegate = new ThreadStart(download.StartDownload); download.DownloadStarting += download_DownloadStarting; download.DownloadCompleted += download_DownloadCompleted; Thread t = new Thread(tsDelegate); t.Name = row.Cells[CELLHREF].Value.ToString(); _threads.Add(t); _instances.Add(download); } catch (Exception ex) { row.Cells[CELLHREF].Style.ForeColor = Color.Red; row.Cells[CELLCOLOR].Style.BackColor = Color.Red; row.Cells[CELLSTATUS].Value = "Erreur : " + ex.Message; } } } private void StartDownload() { int j = 0; int limit = int.Parse(textBox1.Text); int iCount = 0; lock (_lockObject) iCount = _instances.Count; if (iCount != 0) { foreach (Thread thread in _threads) { FileDownloader file = ((FileDownloader)_instances[j]); if (file.IsStarted == false) { lock (_lockObject) { thread.Start(); _activeDownloadCount++; } } if (_activeDownloadCount == limit) { break; } j++; } } } private void download_DownloadStarting(FileDownloader thread) { SetStatus("Telechargement", thread); } delegate void delSetStatus(string Status, FileDownloader f); private void SetStatus(string Status, FileDownloader f) { if (dtgvListFiles.InvokeRequired) { delSetStatus s = new delSetStatus(SetStatus); this.Invoke(s, new object[] {Status, f}); } else { if(f._isDownloaded == false && f.IsStarted == true) //TODO: a revoir { dtgvListFiles.Rows[f.RowIndex].Cells[CELLSTATUS].Value = "En cours"; dtgvListFiles.Rows[f.RowIndex].Cells[CELLCOLOR].Style.BackColor = Color.Blue; } else { if(f._IsDownloadSuccessful) { dtgvListFiles.Rows[f.RowIndex].Cells[CELLSTATUS].Value = "Terminé"; dtgvListFiles.Rows[f.RowIndex].Cells[CELLCOLOR].Style.BackColor = Color.Green; } else { dtgvListFiles.Rows[f.RowIndex].Cells[CELLSTATUS].Value = "ERREUR"; dtgvListFiles.Rows[f.RowIndex].Cells[CELLHREF].Style.ForeColor = Color.Red; dtgvListFiles.Rows[f.RowIndex].Cells[CELLCOLOR].Style.BackColor = Color.Red; } } } } private void download_DownloadCompleted(FileDownloader thread, bool isSuccess) { lock (_lockObject) _activeDownloadCount--; SetStatus("Terminé", thread); SetProgressBar(); RemoveFromInternalPool(thread); StartDownload(); } delegate void SetProgressBarCallback(); private void SetProgressBar() { if (progressBar1.InvokeRequired) { SetProgressBarCallback p = new SetProgressBarCallback(SetProgressBar); this.Invoke(p); } else { lock (_lockObject) progressBar1.Value++; } } private void RemoveFromInternalPool(FileDownloader thread) { int i = 0; foreach (FileDownloader f in _instances) { if (f == thread) { lock (_lockObject)// If the file has downloaded, remove it from our pool. { _threads.Remove(_threads[i]); _instances.Remove(f); break; } } i++; } } }
Un petit coup de main ne serait pas de refus pour comprendre ce qui se passe car là je ne vois pas du tout....
Partager