/// <summary> /// Start the process asynchronously, use <see cref="OnProcessExit"/> event to know when the process is done /// </summary> /// <param name="arguments">Each argument is expected to be quoted if necessary and double quotes escaped with a second double quote (use quoter).</param> /// <param name="silent"></param> protected virtual void ExecuteAsyncProcess(ProcessArgs arguments = null, bool silent = true) { PrepareStart(arguments, silent); _cancelRegistration = CancelToken?.Register(OnCancellation); _process.Start(); if (RedirectOutput) { // Asynchronously read the standard output of the spawned process // This raises OutputDataReceived events for each line of output _process.BeginOutputReadLine(); _process.BeginErrorReadLine(); } }
protected override async Task ScanInternal(ScannedImageSource.Concrete source) { await Task.Factory.StartNew(async() => { if (UseWorker) { var parentHandle = DialogParent?.SafeHandle() ?? IntPtr.Zero; try { using (var worker = workerServiceFactory.Create()) { worker.Callback.ImageCallback += (img, tempPath) => { if (tempPath != null) { scannedImageHelper.RunBackgroundOcr(img, ScanParams, tempPath); } source.Put(img); }; CancelToken.Register(worker.Service.CancelTwainScan); await worker.Service.TwainScan(ScanDevice, ScanProfile, ScanParams, parentHandle); } } finally { if (parentHandle != IntPtr.Zero) { // If the worker process hard crashes while a modal window is open, it may leave the parent // window in a state where it can't be interacted with. This fixes that interaction. // // At the Windows API level, a modal window is implemented by doing two things: // 1. Setting the parent on the child window // 2. Disabling the parent window // The first is implicitly undone when the worker process dies. The second is undone here. Win32.EnableWindow(parentHandle, true); } } } else { twainWrapper.Scan(DialogParent, ScanDevice, ScanProfile, ScanParams, CancelToken, source, scannedImageHelper.RunBackgroundOcr); } }, TaskCreationOptions.LongRunning).Unwrap(); }
protected override Task ScanInternal(ScannedImageSource.Concrete source) { if (ScanProfile.ProxyConfig == null) { throw new InvalidOperationException("ScanProfile.ProxyConfig must be specified to use ProxiedScanDriver."); } return(Task.Factory.StartNew(async() => { try { using (var client = clientContextFactory.Create(ScanProfile.ProxyConfig)) { var noUi = ScanParams.NoUi; var form = Invoker.Current.InvokeGet(() => noUi ? null : formFactory.Create <FScanProgress>()); var pageNumber = 1; var sem = new Semaphore(0, int.MaxValue); client.Callback.ImageCallback += (imageBytes, indexImage) => { try { indexImage.FileName = RecoveryImage.GetNextFileName() + Path.GetExtension(indexImage.FileName); var recoveryFilePath = Path.Combine(RecoveryImage.RecoveryFolder.FullName, indexImage.FileName); File.WriteAllBytes(recoveryFilePath, imageBytes); var image = new ScannedImage(indexImage); using (var bitmap = new Bitmap(new MemoryStream(imageBytes))) { scannedImageHelper.PostProcessStep2(image, bitmap, ScanProfile, ScanParams, pageNumber++, false); } source.Put(image); if (form != null) { form.PageNumber = pageNumber; Invoker.Current.SafeInvoke(() => form.RefreshStatus()); } } finally { sem.Release(); } }; var scanTask = client.Service.Scan(ScanProfile, ScanParams).ContinueWith(t => { for (var i = 0; i < t.Result; i++) { sem.WaitOne(); } }); if (!noUi) { form.PageNumber = pageNumber; form.AsyncTransfer = async() => await scanTask; form.CancelToken.Register(client.Service.CancelScan); } CancelToken.Register(client.Service.CancelScan); if (noUi) { await scanTask; } else if (ScanParams.Modal) { Invoker.Current.SafeInvoke(() => form.ShowDialog()); } else { Invoker.Current.SafeInvoke(() => form.Show()); await scanTask; } } } catch (Exception e) { Log.ErrorException("Error scanning with proxy", e); } }, TaskCreationOptions.LongRunning).Unwrap()); }