private void button_Start_Click(object sender, EventArgs e) { if (SelectedRemoteFiles == null) { return; } button_Start.Enabled = false; var synchronizationContext = SynchronizationContext.Current; var masterjob = JobControler.CreateNewJob(JobControler.JobClass.Normal); masterjob.DisplayName = "Download test"; masterjob.ProgressStr = "wait for download"; runningjob = masterjob; var joblist = new ConcurrentBag <JobControler.Job>(); Parallel.ForEach(SelectedRemoteFiles, (item) => { var job = JobControler.CreateNewJob(JobControler.JobClass.Download, depends: masterjob); job.WeekDepend = true; job.DisplayName = DriveData.GetFullPathfromId(item.id); job.ProgressStr = "Wait for download"; joblist.Add(job); var ct = CancellationTokenSource.CreateLinkedTokenSource(masterjob.ct, job.ct).Token; JobControler.Run(job, (j) => { synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = "download..."; }, null); (j as JobControler.Job).ProgressStr = "download..."; var retry = 5; while (--retry > 0) { ct.ThrowIfCancellationRequested(); try { long length = item.contentProperties.size ?? 0; using (var ret = new AmazonDriveBaseStream(DriveData.Drive, item, autodecrypt: false, parentJob: (j as JobControler.Job))) using (var f = new PositionStream(ret, length)) { f.PosChangeEvent += (src, evnt) => { synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var eo = o as PositionChangeEventArgs; var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = eo.Log; }, evnt); (j as JobControler.Job).ProgressStr = evnt.Log; (j as JobControler.Job).Progress = (double)evnt.Position / evnt.Length; }; f.CopyTo(new NullStream()); } synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = "Done"; }, null); (j as JobControler.Job).ProgressStr = "Done."; (j as JobControler.Job).Progress = 1; break; } catch (OperationCanceledException) { throw; } catch (Exception ex) { Config.Log.LogOut("Download : Error " + ex.Message); continue; } } if (retry == 0) { // failed synchronizationContext.Post( (o) => { if (ct.IsCancellationRequested) { return; } var listitem = listView1.Items.Find(item.id, false).FirstOrDefault(); listitem.SubItems[1].Text = "Failed"; }, null); (j as JobControler.Job).ProgressStr = "Failed"; (j as JobControler.Job).Progress = double.NaN; (j as JobControler.Job).IsError = true; } }); }); JobControler.Run(masterjob, (j) => { masterjob.ProgressStr = "running..."; masterjob.Progress = -1; var ct = (j as JobControler.Job).ct; Task.WaitAll(joblist.Select(x => x.WaitTask(ct: ct)).ToArray()); masterjob.Progress = 1; masterjob.ProgressStr = "done."; }); var afterjob = JobControler.CreateNewJob(JobControler.JobClass.Clean, depends: masterjob); afterjob.DisplayName = "clean up"; afterjob.DoAlways = true; JobControler.Run(afterjob, (j) => { afterjob.ProgressStr = "done."; afterjob.Progress = 1; runningjob = null; synchronizationContext.Post((o) => { button_Start.Enabled = true; }, null); }); }
public async Task <FileMetadata_Info> uploadFile(string filename, string parent_id = null, string uploadname = null, string uploadkey = null, PoschangeEventHandler process = null, CancellationToken ct = default(CancellationToken)) { int transbufsize = Config.UploadBufferSize; if (Config.UploadLimit < transbufsize) { transbufsize = (int)Config.UploadLimit; } if (transbufsize < 1 * 1024) { transbufsize = 1 * 1024; } if (Config.UploadTrick1) { transbufsize = 256 * 1024; } Config.Log.LogOut("\t[uploadFile] " + filename); string error_str; string HashStr = ""; using (var client = new HttpClient()) { client.Timeout = TimeSpan.FromDays(1); try { client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Authkey.access_token); var content = new MultipartFormDataContent(); DataContractJsonSerializer jsonSer = new DataContractJsonSerializer(typeof(ItemUpload_Info)); // Serializerを使ってオブジェクトをMemoryStream に書き込み MemoryStream ms = new MemoryStream(); var short_filename = Path.GetFileName(filename); if (uploadname == null) { uploadname = (Config.UseEncryption) ? short_filename + ".enc" : short_filename; if (uploadkey == null) { uploadkey = short_filename; } } else { if (uploadkey == null) { uploadkey = Path.GetFileNameWithoutExtension(uploadname); } } jsonSer.WriteObject(ms, new ItemUpload_Info { name = uploadname, kind = "FILE", parents = string.IsNullOrEmpty(parent_id) ? null : new string[] { parent_id } }); ms.Position = 0; // StreamReader で StringContent (Json) をコンストラクトします。 StreamReader sr = new StreamReader(ms); content.Add(new StringContent(sr.ReadToEnd(), System.Text.Encoding.UTF8, "application/json"), "metadata"); using (var file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 256 * 1024)) { HashStream contStream = null; Stream cryptStream = null; StreamContent fileContent = null; IHashStream hasher = null; if (Config.UseEncryption) { if (Config.CryptMethod == CryptMethods.Method1_CTR) { cryptStream = new CryptCTR.AES256CTR_CryptStream(file, uploadkey); contStream = new HashStream(cryptStream, new MD5CryptoServiceProvider()); hasher = contStream; } if (Config.CryptMethod == CryptMethods.Method2_CBC_CarotDAV) { cryptStream = new CryptCarotDAV.CryptCarotDAV_CryptStream(file); contStream = new HashStream(cryptStream, new MD5CryptoServiceProvider()); hasher = contStream; } } else { contStream = new HashStream(file, new MD5CryptoServiceProvider()); hasher = contStream; } using (cryptStream) using (contStream) using (var thstream = new ThrottleUploadStream(contStream, ct)) using (var f = new PositionStream(thstream)) { if (process != null) { f.PosChangeEvent += process; } fileContent = new StreamContent(f, transbufsize); fileContent.Headers.ContentLength = f.Length; fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); content.Add(fileContent, "content", Path.GetFileName(filename)); using (fileContent) { if (Config.UploadTrick1) { if (DelayUploadReset != null) { if (Interlocked.CompareExchange(ref Config.UploadLimitTemp, Config.UploadLimit, 10 * 1024) == 10 * 1024) { DelayUploadReset = Task.Delay(TimeSpan.FromSeconds(10)).ContinueWith((task) => { Interlocked.Exchange(ref Config.UploadLimit, Config.UploadLimitTemp); DelayUploadReset = null; }); } } } var response = await client.PostAsync( Config.contentUrl + "nodes?suppress=deduplication", content, ct).ConfigureAwait(false); HashStr = hasher.Hash.ToLower(); response.EnsureSuccessStatusCode(); string responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false); // Above three lines can be replaced with new helper method in following line // string body = await client.GetStringAsync(uri); var ret = ParseResponse <FileMetadata_Info>(responseBody); if (ret.contentProperties?.md5 != HashStr) { throw new AmazonDriveUploadException(HashStr); } return(ret); } } } } catch (AmazonDriveUploadException) { throw; } catch (HttpRequestException ex) { error_str = ex.Message; Config.Log.LogOut("\t[uploadFile] " + error_str); throw new AmazonDriveUploadException(HashStr, ex); } catch (OperationCanceledException) { throw; } catch (Exception ex) { error_str = ex.ToString(); Config.Log.LogOut("\t[uploadFile] " + error_str); throw; } } }