/// <summary> /// Do stuff /// </summary> private void Work() { // If the main token (the one thrown by the main application) requests cancellation, // then cancel the trasfer too. using (CancellationTokenRegistration ctr = MainCancellationToken.Register(() => Cancel())) { // Prepare File PrepareFile(); // Don't start if user cancelled or the two above had errors if (AbortTransfer.IsCancellationRequested || MainCancellationToken.IsCancellationRequested) { Progress.CurrentActivity = "Operation cancelled"; Progress.IsError = true; DestroyIncompleteFile(); return; } //------------------------------------ // Read from network //------------------------------------ Loader = Task.Run(() => Load(), AbortTransfer.Token); //------------------------------------ // Write to file //------------------------------------ Writer = Task.Run(() => Write(), AbortTransfer.Token); Progress.CurrentActivity = "Transferring file..."; Writer.Wait(); Loader.Wait(); Writer.Dispose(); Loader.Dispose(); if (!Progress.IsError) { Progress.CurrentActivity = "Transfer Completed"; Progress.TextColor = "Green"; } else { DestroyIncompleteFile(); } } Buffer.Clear(); //------------------------------------ // Parse the next request //------------------------------------ if (!ParseHello()) { // Reject and get the next file Reject(); return; } // Accept the transfer request (if the parsed messages wasn't ENDOC) if (!StopReceiving) { Accept(); } }
/// <summary> /// Actually do stuff /// </summary> /// <param name="UseExistingProgress">If a new progress bar should be created</param> private void Work(bool UseExistingProgress = false) { if (!UseExistingProgress) { Progress = new TransferProgress { UserName = Receiver.Name, UserPicture = Receiver.PicBytes, FromOrTo = "to", Parent = this }; // Add new Progress Bar Application.Current.Dispatcher.Invoke(() => { ((ObservableCollection <TransferProgress>)Application.Current.Properties["TransferProgresses"]).Insert(0, Progress); }); } // Check the file if (!GetFileData()) { return; } // Update the progress bar with the new data just obtained Progress.FileName = FileName; Progress.Maximum = FileSize; // Don't even start transferring if user already cancelled if (!MainCancellationToken.IsCancellationRequested) { // Set up the cancellation token AbortTransfer = new CancellationTokenSource(); // Send File data Response response = SendHello(); if (response != Response.ACCEPTED) { if (response == Response.REJECTED) { StopSending = true; } Progress.CurrentActivity = "Request rejected"; Progress.IsError = true; return; } if (AbortTransfer.Token.IsCancellationRequested) { Progress.CurrentActivity = "Operation Cancelled."; Progress.IsError = true; // Useless, but just to keep things clean StopSending = true; return; } // If the main token (the one thrown by the main application) requests cancellation, // then cancel the trasfer too. using (CancellationTokenRegistration ctr = MainCancellationToken.Register(() => Cancel())) { //------------------------------------ // Load the file //------------------------------------ Loader = Task.Run(() => { Load(); }, AbortTransfer.Token); //------------------------------------ // Send the file //------------------------------------ Sender = Task.Run(() => { Transmit(); }, AbortTransfer.Token); Progress.CurrentActivity = "Transferring..."; // Wait for them to finish (Or that the user cancels them). // NOTE: I can't wrap the Task definition in using(), // because I need to wait for them to finish! I can't dispose them earlier! Sender.Wait(); Loader.Wait(); // Dispose the tasks Sender.Dispose(); Loader.Dispose(); if (!Progress.IsError) { Progress.CurrentActivity = "Transfer completed"; Progress.TextColor = "Green"; } } // Dispose it; AbortTransfer.Dispose(); // Clean up // If you're here, it means that the sender and loader have exited, so no need to lock. Buffer.Clear(); } }