public async Task <Dictionary <string, Record> > writeGeoTag(Dictionary <string, Record> recordDict, BlockingCollection <string> fileQueue, string inPath, string outPath) { int mQueueSize = fileQueue.Count; progressForm = new ProgressForm("Writing geotags to photos..."); string[] _files = Directory.GetFiles(inPath); progressForm.Show(); progressForm.BringToFront(); progressForm.cancel += cancelImport; cts = new CancellationTokenSource(); var token = cts.Token; var progressHandler1 = new Progress <int>(value => { progressForm.ProgressValue = value; progressForm.Message = "Geotagging, please wait... " + value.ToString() + "% completed\n" + geoTagCount + " of " + mQueueSize + " photos geotagged\n" + "Photos with no geomark: " + stationaryCount + "\n" + "Photos with no gps point: " + errorCount + "\n"; }); var progressValue = progressHandler1 as IProgress <int>; geoTagCount = 0; errorCount = 0; stationaryCount = 0; Dictionary <string, Record> newRecordDict = new Dictionary <string, Record>(); int processors = Environment.ProcessorCount; int minWorkerThreads = processors; int minIOThreads = processors; int maxWorkerThreads = processors; int maxIOThreads = processors; //ThreadPool.SetMinThreads(minWorkerThreads, minIOThreads); ThreadPool.SetMaxThreads(maxWorkerThreads, maxIOThreads); await Task.Factory.StartNew(() => { try { while (fileQueue.Count != 0) { if (token.IsCancellationRequested) { token.ThrowIfCancellationRequested(); } Parallel.Invoke( () => { ThreadInfo threadInfo = new ThreadInfo(); threadInfo.OutPath = outPath; threadInfo.Length = mQueueSize; threadInfo.ProgressHandler = progressHandler1; threadInfo.File = fileQueue.Take(); try { Record r = recordDict[Path.GetFileNameWithoutExtension(threadInfo.File)]; threadInfo.Record = r; if (r.GeoMark) { Record newRecord = null; newRecord = ProcessFile(threadInfo).Result; newRecordDict.Add(r.PhotoName, r); } else { object a = "nogps"; incrementGeoTagError(a); } } catch (KeyNotFoundException ex) { object a = "nokey"; incrementGeoTagError(a); } }); } } catch (OperationCanceledException) { cts.Dispose(); } }, cts.Token); progressForm.Invoke( new MethodInvoker(() => progressValue.Report(100) )); progressForm.enableOK(); progressForm.disableCancel(); return(newRecordDict); }