프로젝트

일반

사용자정보

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

markus / KCOM / PageManager / PageStorage - 복사본(2).cs @ b1fc6833

이력 | 보기 | 이력해설 | 다운로드 (10.4 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
using System.Windows.Media.Imaging;
9

    
10
namespace KCOM.PageManager
11
{
12
    public class PageStorage
13
    {
14
        private const int DEFUALT_TALK_PAGE_COUNT = 10;
15

    
16
        public event EventHandler<PageLoadCompletedEventArgs> PageLoadCompleted;
17

    
18
        List<int> WorkItems = new List<int>();
19
        ConcurrentBag<PageItem> fileItems = new ConcurrentBag<PageItem>();
20
        BackgroundWorker backgroundWorker;
21

    
22
        //List<PageItem> fileItems = new List<PageItem>();
23
        string _localStorage;
24
        string _fileExt;
25
        string _BaseUri;
26
        int _TotalPages;
27
        int _TakeCount;
28

    
29
        bool IsDownload = false;
30

    
31
        BitmapFrame PageImage;
32

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

    
46
                System.IO.Directory.CreateDirectory(_localStorage);
47

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

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

    
61
        private async void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
62
        {
63

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

    
72
                        if (WorkItems.TryFrist(true, out item))
73
                        {
74
                            var result = await DownloadPageAsync(item, null);
75

    
76
                            //if (!result.IsDownLoad)
77
                            //{
78
                            //    System.Threading.Thread.Sleep(100);
79
                            //}
80
                            //await Task.Delay(100);
81
                            //System.Threading.Thread.Sleep(100);
82
                            //backgroundWorker.ReportProgress(fileItems.Count / _TotalPages * 100);
83
                        }
84

    
85
                        System.Diagnostics.Debug.WriteLine("backgroundWorker end");
86
                    }
87
                    catch (Exception ex)
88
                    {
89
                        System.Diagnostics.Debug.WriteLine(ex.ToString());
90
                    }
91
                }
92
            }
93
        }
94

    
95
        public void ResetImage()
96
        {
97
            //if (PageImage != null)
98
            //{
99
            //    PageImage = null;
100
            //}
101

    
102
            //PageImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
103

    
104
        }
105

    
106
        public async Task<BitmapFrame> GetPageImageAsync(System.Threading.CancellationToken cts, int PageNo, bool IsRestart = false)
107
        {
108
            try
109
            {
110

    
111
                var localUri = await GetPageUriAsync(null, PageNo);
112

    
113
                if (localUri != null || !cts.IsCancellationRequested)
114
                {
115
                    PageImage = BitmapFrame.Create(localUri, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
116
                }
117
            }
118
            catch (Exception ex)
119
            {
120
                throw new Exception("GetPageImageAsync(int PageNo,bool IsRestart =false)", ex);
121
            }
122
            finally
123
            {
124
            }
125

    
126
            return PageImage;
127
        }
128

    
129
        private void DownloadWorkAsync(int startPage, int TakeCount)
130
        {
131
            if(0 < _TakeCount && startPage < _TotalPages)
132
            {
133
                int takecount = _TakeCount;
134

    
135
                if (_TotalPages < startPage + takecount)
136
                {
137
                    takecount = _TotalPages - startPage;
138
                    _TakeCount = 0;
139
                }
140

    
141
                WorkItems.AddRange(Enumerable.Range(startPage, TakeCount));
142
            }
143
            if (!backgroundWorker.IsBusy && WorkItems.Count() > 0)
144
            {
145
                backgroundWorker.RunWorkerAsync();
146
            }
147
        }
148

    
149
        public async Task<Uri> GetPageUriAsync(System.Threading.CancellationToken? cts, int PageNo, bool IsRestart = false)
150
        {
151
            Uri result = null;
152

    
153
            try
154
            {
155
                System.Diagnostics.Debug.WriteLine("GetPageAsync");
156

    
157
                var pageItem = await DownloadPageAsync(PageNo, cts);
158

    
159
                // 다음 페이지가 미리 다운로드 되도록 추가
160
                if (pageItem != null && 0 < _TakeCount && PageNo + 1 < _TotalPages)
161
                {
162
                    int takecount = _TakeCount;
163

    
164
                    if (_TotalPages < PageNo + 1 + takecount)
165
                    {
166
                        takecount = _TotalPages - PageNo + 1;
167
                    }
168

    
169
                    DownloadWorkAsync(PageNo + 1, takecount);
170
                    //var takePageNoList = Enumerable.Range(PageNo + 1, _TakeCount);
171
                }
172

    
173
                result = pageItem.LocalUri;
174
            }
175
            catch (Exception ex)
176
            {
177
                if (cts != null)
178
                {
179
                    if (cts.Value.IsCancellationRequested)
180
                    {
181
                        return result;
182
                    }
183
                }
184

    
185
                if (!IsRestart)
186
                {
187
                    await Task.Delay(100);
188

    
189
                    result = await GetPageUriAsync(cts, PageNo, true);
190
                }
191
                //throw new Exception("GetPageAsync(string BasePageUri,int PageNo)", ex);
192
            }
193
            finally
194
            {
195
            }
196

    
197
            return result;
198
        }
199

    
200
        public async Task<PageItem> DownloadPageAsync(int PageNo, System.Threading.CancellationToken? cts)
201
        {
202
            PageItem result = new PageItem { PageNo = PageNo };
203

    
204
            try
205
            {
206
                var page = fileItems.Where(x => x.PageNo == PageNo).ToList();
207

    
208
                if (page.Count > 0)
209
                {
210
                    System.Diagnostics.Debug.WriteLine("DownloadPageAsync fileItems");
211

    
212
                    result = page.First();
213

    
214
                    /// 파일 체크 후 없으면 다시 다운로드
215
                    if (!System.IO.File.Exists(result.LocalFilePath))
216
                    {
217
                        //fileItems.(result);
218

    
219
                        result = await DownloadPageAsync(PageNo, cts);
220
                    }
221
                }
222
                else
223
                {
224

    
225
                    System.Diagnostics.Debug.WriteLine("DownloadPageAsync down");
226

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

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

    
231
                    result = new PageItem
232
                    {
233
                        PageNo = PageNo,
234
                        OriginalUri = originalUri,
235
                        LocalUri = new Uri(downloadFilePath, UriKind.Absolute),
236
                        LocalFilePath = downloadFilePath
237
                    };
238

    
239
                    if (fileItems.Where(x => x.PageNo == PageNo).Count() == 0)
240
                    {
241
                        fileItems.Add(result);
242
                    }
243

    
244
                    using (System.Net.WebClient client = new System.Net.WebClient())
245
                    {
246
                        client.UseDefaultCredentials = true;
247
                        System.Net.IWebProxy webProxy = client.Proxy;
248

    
249
                        if (webProxy != null)
250
                        {
251
                            // Use the default credentials of the logged on user.
252
                            webProxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
253
                        }
254

    
255
                        if (cts != null)
256
                        {
257
                            client.DownloadProgressChanged += (snd, ect) =>
258
                            {
259
                                IsDownload = client.IsBusy;
260

    
261
                                if (cts.Value.IsCancellationRequested)
262
                                {
263
                                    client.CancelAsync();
264
                                }
265
                            };
266
                        }
267

    
268
                        client.DownloadFileCompleted += (snd, evt) =>
269
                        {
270
                            result.IsDownLoad = true;
271

    
272
                            PageLoadCompleted?.Invoke(this, new PageLoadCompletedEventArgs(result));
273
                            System.Diagnostics.Debug.WriteLine("Download : " + downloadFilePath);
274
                        };
275

    
276
                        await client.DownloadFileTaskAsync(originalUri, downloadFilePath);
277

    
278
                    }
279

    
280
                    //}
281
                    //System.Diagnostics.Debug.WriteLine("Download : " + result.LocalFilePath);
282
                }
283
            }
284
            catch (Exception ex)
285
            {
286
                throw new Exception("DownloadPageAsync : ", ex);
287
            }
288
            finally
289
            {
290
                IsDownload = false;
291
            }
292

    
293
            return result;
294
        }
295

    
296
        public void Clear()
297
        {
298
            try
299
            {
300
                ResetImage();
301
            }
302
            catch (Exception ex)
303
            {
304
                System.Diagnostics.Debug.WriteLine(ex.ToString());
305
            }
306

    
307
            try
308
            {
309
                backgroundWorker.CancelAsync();
310
                backgroundWorker.Dispose();
311

    
312
                foreach (var item in fileItems)
313
                {
314
                    System.IO.File.Delete(item.LocalFilePath);
315
                }
316

    
317
                System.IO.Directory.Delete(_localStorage, true);
318
            }
319
            catch (Exception ex)
320
            {
321
                System.Diagnostics.Debug.WriteLine(ex.ToString());
322
            }
323
        }
324
    }
325
}
클립보드 이미지 추가 (최대 크기: 500 MB)