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);
        }