private async Task FileUpload_Change(IEnumerable <IFileReference> files) { foreach (var file in files) { var fileInfo = await file.ReadFileInfoAsync(); if (fileInfo.Size > _maxSize) { return; } string filename = FormatFilename(fileInfo.Name); Stream uploadStream = await file.OpenReadAsync(); Func <Stream, CancellationToken, IProgress <IUploadProgress>, Task> uploadTask = async(stream, cancellationToken, progress) => { await downloadFiles.AddAsync(_download.Id, filename, stream, cancellationToken, progress); }; var progressTask = new FileUploadTask(filename, _download, uploadStream, uploadTask); progressTask.OnComplete += async t => await RefreshFileList(); taskState.Add(progressTask); } }
private void ReadCallback(IAsyncResult a) { Tuple <HttpWebRequest, FileUploadTask, int> args = (Tuple <HttpWebRequest, FileUploadTask, int>)a.AsyncState; HttpWebRequest webrequest = args.Item1; FileUploadTask fileTask = args.Item2; try { using (Stream requestStream = webrequest.EndGetRequestStream(a)) { using (FileStream fs = m_FileInfo.OpenRead()) { fs.Seek(fileTask.StartPosition, SeekOrigin.Begin); byte[] buffer = new Byte[4096]; long tempTotal = 0; while (tempTotal < fileTask.Length) { long bytesRead = fileTask.Length - tempTotal; if (bytesRead > buffer.Length) { bytesRead = buffer.Length; } fs.Read(buffer, 0, (int)bytesRead); requestStream.Write(buffer, 0, (int)bytesRead); tempTotal += bytesRead; } fs.Close(); } requestStream.Close(); } webrequest.BeginGetResponse(new AsyncCallback(WriteCallback), args); } catch (Exception ex) { ComponentFactory.GetComponent <ILog>().LogError(ex); var tmp = new UploadErrorOccuredEventEventArgs { FileIdentity = m_FileIdentity, FileInfo = m_FileInfo, Exception = ex }; m_Exception = tmp; lock (m_TaskQueue_SyncObj) { m_TaskQueue.Enqueue(fileTask); } ExecuteUploadTask(args.Item3); // 继续任务处理 } }
private void ExecuteUploadTask(int threadID) { // 判断ToCancel的优先级最高,不管是否发生了异常,还是最后一个task都已经上传完毕, // 一旦调用Cancel,异常、上传完毕都可以被忽略,都认为上传被取消 if (m_UploadStatus == UploadStatus.ToCancel) { if (EndThread()) { DeleteFileFromServer(); m_UploadStatus = UploadStatus.Stopped; OnUploadCanceled(new UploadCanceledEventArgs { FileIdentity = m_FileIdentity, FileInfo = m_FileInfo, TotalUploadedDataLength = m_CurrentUploadLength }); } return; } if (m_Exception != null) { if (EndThread()) { m_Exception.TotalUploadedDataLength = m_CurrentUploadLength; var tmp = m_Exception; m_Exception = null; m_UploadStatus = UploadStatus.Suspended; OnUploadErrorOccured(tmp); } return; } // 在判断是否需要暂停前,要先判断一下任务是否已经都完成了;如果不首先判断任务是否都完成,可能会出现一种情况: // 当最后一个任务在上传时,才调用了Suspend方法将状态置为ToSuspend;然后线程执行到这里判断状态为ToSuspend了后就进入暂停状态; // 而当调用了Resume方法的时候,状态会再次变为Uploading,但是此时Queue里已经没有任务了,那么也就不会再开启上传线程, // 那么状态永远都是Uploading,永远无法完成 // 所以为了避免这种情况发生,在判断ToSuspend之前需要先看看任务是否都已经上传完毕,如果是则直接变成已上传完毕了,之前发生的暂停操作就无效了 if (m_TaskQueue.Count <= 0) { if (EndThread()) { m_UploadStatus = UploadStatus.Stopped; CallServiceUploadStopped(); } return; } if (m_UploadStatus == UploadStatus.ToSuspend) { if (EndThread()) { m_UploadStatus = UploadStatus.Suspended; OnUploadSuspended(new UploadSuspendedEventArgs { FileIdentity = m_FileIdentity, FileInfo = m_FileInfo, TotalUploadedDataLength = m_CurrentUploadLength }); } return; } FileUploadTask task = null; if (m_TaskQueue.Count > 0) { lock (m_TaskQueue_SyncObj) { if (m_TaskQueue.Count > 0) { task = m_TaskQueue.Dequeue(); } } } if (task == null) { if (EndThread()) { m_UploadStatus = UploadStatus.Stopped; CallServiceUploadStopped(); } return; } try { string url = m_Url + "?FileIdentity=" + HttpUtility.UrlEncode(m_FileIdentity) + "&StartPosition=" + task.StartPosition; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.BeginGetRequestStream(new AsyncCallback(ReadCallback), new Tuple <HttpWebRequest, FileUploadTask, int>(request, task, threadID)); } catch (Exception ex) { ComponentFactory.GetComponent <ILog>().LogError(ex); var tmp = new UploadErrorOccuredEventEventArgs { FileIdentity = m_FileIdentity, FileInfo = m_FileInfo, Exception = ex }; m_Exception = tmp; lock (m_TaskQueue_SyncObj) { m_TaskQueue.Enqueue(task); } ExecuteUploadTask(threadID); // 继续任务处理 } }