프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / DownloadManager / PageStorage.cs @ 2007ecaa

이력 | 보기 | 이력해설 | 다운로드 (9.49 KB)

1
using System;
2
using System.Collections.Concurrent;
3
using System.Collections.Generic;
4
using System.ComponentModel;
5
using System.Linq;
6
using System.Text;
7
using System.Threading.Tasks;
8

    
9
namespace KCOM.PageManager
10
{
11
    public class PageStorage
12
    {
13
        public event EventHandler<PageLoadCompletedEventArgs> PageLoadCompleted;
14

    
15
        private const int DEFUALT_TALK_PAGE_COUNT = 10;
16

    
17
        List<int> WorkItems = new List<int>();
18
        ConcurrentBag<PageItem> fileItems = new ConcurrentBag<PageItem>();
19
        BackgroundWorker backgroundWorker;
20
        
21
        string _localStorage;
22
        string _fileExt;
23
        string _BaseUri;
24
        int _TotalPages;
25
        int _TakeCount;
26

    
27
        bool IsWork = false;
28
        bool IsDownload = false;
29

    
30
        public PageStorage(string BaseUri, string localStoragePath, string fileExt, int totalPages, int takeCount = 5)
31
        {
32
            try
33
            {
34
                backgroundWorker = new BackgroundWorker { WorkerSupportsCancellation = true, WorkerReportsProgress = true };
35
                backgroundWorker.DoWork += BackgroundWorker_DoWork;
36
                backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
37
                _fileExt = fileExt;
38
                _BaseUri = BaseUri;
39
                _localStorage = localStoragePath;
40
                _TotalPages = totalPages;
41
                _TakeCount = takeCount;
42

    
43
                System.IO.Directory.CreateDirectory(_localStorage);
44

    
45
                //backgroundWorker.RunWorkerAsync(new int[] { 1, 10 });
46
            }
47
            catch (Exception ex)
48
            {
49
                throw new Exception("PageStorage", ex);
50
            }
51
        }
52

    
53
        private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
54
        {
55
            System.Diagnostics.Debug.WriteLine(_fileExt + ":" + e.ProgressPercentage.ToString() + "%");
56
        }
57

    
58
        private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
59
        {
60
             DownloadWork();
61
        }
62

    
63
        private void DownloadWork()
64
        { 
65
            while (WorkItems.Count > 0)
66
            {
67
                if (!IsDownload)
68
                {
69
                    int item = -1;
70
                    try
71
                    {
72

    
73
                        if (WorkItems.TryFrist(true, out item))
74
                        {
75
                            var result = DownloadPageAsync(item, null);
76
                        }
77
                    }
78
                    catch (Exception ex)
79
                    {
80
                        System.Diagnostics.Debug.WriteLine(ex.ToString());
81
                    }
82
                }
83

    
84
                System.Threading.Thread.Sleep(10);
85

    
86
            }
87

    
88
            IsWork = false;
89
        }
90

    
91
        public async void DownloadWorkAsync(int startPage, int TakeCount)
92
        {
93
            if (0 < _TakeCount && startPage < _TotalPages)
94
            {
95
                int takecount = _TakeCount;
96

    
97
                if (_TotalPages < startPage + takecount)
98
                {
99
                    takecount = _TotalPages - startPage;
100
                    _TakeCount = 0;
101
                }
102

    
103
                WorkItems.AddRange(Enumerable.Range(startPage, TakeCount - 1));
104
            }
105

    
106
            if (!IsWork && WorkItems.Count() > 0)
107
            {
108
                IsWork = true;
109
                await Task.Run(() => DownloadWork());
110
            }
111
            //if (!backgroundWorker.IsBusy && WorkItems.Count() > 0)
112
            //{
113
            //    backgroundWorker.RunWorkerAsync();
114
            //}
115
        }
116

    
117
        public  void DownloadWork(int startPage, int TakeCount)
118
        {
119
            if (0 < _TakeCount && startPage < _TotalPages)
120
            {
121
                WorkItems.AddRange(Enumerable.Range(startPage, _TotalPages));
122
            }
123

    
124
            if (!IsWork && WorkItems.Count() > 0)
125
            {
126
                IsWork = true;
127
                DownloadWork();
128
            }
129
        }
130

    
131
        public async Task<Uri> GetPageUriAsync(System.Threading.CancellationToken? cts, int PageNo, bool IsRestart = false)
132
        {
133
            IsDownload = true;
134

    
135
            Uri result = null;
136

    
137
            try
138
            {
139
                System.Diagnostics.Debug.WriteLine("GetPageAsync");
140

    
141
                var pageItem = await DownloadPageAsync(PageNo, cts);
142

    
143
                // 다음 페이지가 미리 다운로드 되도록 추가
144
                if (pageItem != null && 0 < _TakeCount && PageNo + 1 < _TotalPages)
145
                {
146
                    int takecount = _TakeCount;
147

    
148
                    if (_TotalPages < PageNo + 1 + takecount)
149
                    {
150
                        takecount = _TotalPages - PageNo + 1;
151
                    }
152

    
153
                    DownloadWorkAsync(PageNo + 1, takecount);
154
                    //var takePageNoList = Enumerable.Range(PageNo + 1, _TakeCount);
155
                }
156

    
157
                result = pageItem.LocalUri;
158
            }
159
            catch (Exception ex)
160
            {
161
                if (cts != null)
162
                {
163
                    if (cts.Value.IsCancellationRequested)
164
                    {
165
                        return result;
166
                    }
167
                }
168

    
169
                if (!IsRestart)
170
                {
171
                    await Task.Delay(100);
172

    
173
                    result = await GetPageUriAsync(cts, PageNo, true);
174
                }
175
                //throw new Exception("GetPageAsync(string BasePageUri,int PageNo)", ex);
176
            }
177
            finally
178
            {
179
                IsDownload = false;
180
            }
181

    
182
            return result;
183
        }
184

    
185
        public async Task<PageItem> DownloadPageAsync(int PageNo, System.Threading.CancellationToken? cts)
186
        {
187
            IsDownload = true;
188
            PageItem result = new PageItem { PageNo = PageNo };
189

    
190
            try
191
            {
192
                var page = fileItems.Where(x => x.PageNo == PageNo).ToList();
193

    
194
                if (page.Count > 0)
195
                {
196
                    System.Diagnostics.Debug.WriteLine("DownloadPageAsync fileItems");
197

    
198
                    result = page.First();
199

    
200
                    /// 파일 체크 후 없으면 다시 다운로드
201
                    if (!System.IO.File.Exists(result.LocalFilePath))
202
                    {
203
                        //fileItems.(result);
204

    
205
                        result = await DownloadPageAsync(PageNo, cts);
206
                    }
207
                }
208
                else
209
                {
210

    
211
                    System.Diagnostics.Debug.WriteLine("DownloadPageAsync down");
212

    
213
                    string downloadFilePath = System.IO.Path.Combine(_localStorage, PageNo.ToString() + "." + _fileExt);
214

    
215
                    Uri originalUri = new Uri(_BaseUri.Replace("{PageNo}", PageNo.ToString()));
216

    
217
                    result = new PageItem
218
                    {
219
                        PageNo = PageNo,
220
                        OriginalUri = originalUri,
221
                        LocalUri = new Uri(downloadFilePath, UriKind.Absolute),
222
                        LocalFilePath = downloadFilePath
223
                    };
224

    
225
                    if (fileItems.Where(x => x.PageNo == PageNo).Count() == 0)
226
                    {
227
                        fileItems.Add(result);
228
                    }
229

    
230
                    using (System.Net.WebClient client = new System.Net.WebClient())
231
                    {
232
                        client.UseDefaultCredentials = true;
233
                        System.Net.IWebProxy webProxy = client.Proxy;
234

    
235
                        if (webProxy != null)
236
                        {
237
                            // Use the default credentials of the logged on user.
238
                            webProxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
239
                        }
240

    
241
                        if (cts != null)
242
                        {
243
                            client.DownloadProgressChanged += (snd, ect) =>
244
                            {
245
                                IsDownload = client.IsBusy;
246

    
247
                                if (cts.Value.IsCancellationRequested)
248
                                {
249
                                    client.CancelAsync();
250
                                }
251
                            };
252
                        }
253

    
254
                        client.DownloadFileCompleted += (snd, evt) =>
255
                        {
256
                            result.IsDownLoad = true;
257

    
258
                            PageLoadCompleted?.Invoke(this, new PageLoadCompletedEventArgs(result));
259
                            System.Diagnostics.Debug.WriteLine("Download : " + downloadFilePath);
260
                        };
261

    
262
                        await client.DownloadFileTaskAsync(originalUri, downloadFilePath);
263

    
264
                    }
265

    
266
                    //}
267
                    //System.Diagnostics.Debug.WriteLine("Download : " + result.LocalFilePath);
268
                }
269
            }
270
            catch (Exception ex)
271
            {
272
                throw new Exception("DownloadPageAsync : ", ex);
273
            }
274
            finally
275
            {
276
                IsDownload = false;
277
            }
278

    
279
            return result;
280
        }
281

    
282
        public void Clear()
283
        {
284
            try
285
            {
286
                backgroundWorker.CancelAsync();
287
                backgroundWorker.Dispose();
288

    
289
                foreach (var item in fileItems)
290
                {
291
                    System.IO.File.Delete(item.LocalFilePath);
292
                }
293

    
294
                System.IO.Directory.Delete(_localStorage, true);
295
            }
296
            catch (Exception ex)
297
            {
298
                System.Diagnostics.Debug.WriteLine(ex.ToString());
299
            }
300
        }
301
    }
302
}
클립보드 이미지 추가 (최대 크기: 500 MB)