public virtual async Task <WorkResult <HashFile> > RunAsync(HashFile workunit, IProgress <IWorkProgress <HashFile> > progress = null, CancellationToken token = default(CancellationToken)) { Task t = null; ThreadUnit tu = new ThreadUnit(); try { if (workunit.File == null) { return(new WorkResult <HashFile>(WorkResultStatus.Error, "File not found")); } FileSystemResult <Stream> fs = await workunit.File.OpenReadAsync(); if (fs.Status != Status.Ok) { return(new WorkResult <HashFile>(WorkResultStatus.Error, fs.Error)); } BasicWorkProgress <HashFile> progressdata = new BasicWorkProgress <HashFile> { Command = this, Unit = workunit }; tu.WorkUnit = workunit; tu.FileSize = workunit.File.Size; tu.Buffer = new byte[2][]; tu.Buffer[0] = new byte[BUFFER_SIZE]; tu.Buffer[1] = new byte[BUFFER_SIZE]; tu.BufferNumber = 0; t = Task.Factory.StartNew(HashWorker, tu, token, TaskCreationOptions.LongRunning, TaskScheduler.Current); long read = 0; do { try { tu.CurrentSize = await fs.Result.ReadAsync(tu.Buffer[tu.BufferNumber], 0, BUFFER_SIZE, token); read += tu.CurrentSize; if (token.IsCancellationRequested) { token.ThrowIfCancellationRequested(); } tu.WorkerAutoResetEvent.Set(); if (progress != null) { progressdata.Progress = (double)read * 100 / tu.FileSize; progress.Report(progressdata); } if (tu.Abort) { return(new WorkResult <HashFile>(WorkResultStatus.Error, tu.Error)); } tu.MainAutoResetEvent.WaitOne(); tu.BufferNumber ^= 1; } catch (OperationCanceledException) { tu.CancelWorker(); return(new WorkResult <HashFile>(WorkResultStatus.Canceled, "Operation Canceled")); } catch (Exception e) { tu.CancelWorker(); return(new WorkResult <HashFile>(WorkResultStatus.Error, e.Message)); } } while (tu.CurrentSize != 0); if (tu.Abort) { return(new WorkResult <HashFile>(WorkResultStatus.Error, tu.Error)); } tu.MainAutoResetEvent.WaitOne(); return(new WorkResult <HashFile>(tu.WorkUnit)); } catch (Exception e) { if (t != null) { tu.CancelWorker(); } return(new WorkResult <HashFile>(WorkResultStatus.Error, e.Message)); } }