private async void Merge(object sender, RoutedEventArgs e) { //Encryption and security made this function more than two times bigger :). SecureString pass = null; //The number of files. int count = 0; //Title of first item. string ci = null, result = null; if (FilesBox.Items.Cast <ListBoxItem>().Any(x => x.Tag != null) & MessageDialogResult.Affirmative == await this.ShowMessageAsync("Password protected pdf", "One or more of the pdfs you are merging are password protected. Do you want to protect the merged pdf with a pasword?", MessageDialogStyle.AffirmativeAndNegative, new MetroDialogSettings() { AffirmativeButtonText = "Yes", NegativeButtonText = "No" })) { result = await this.ShowInputAsync("Enter the password for the merged pdf", "Password contain anything"); if (!String.IsNullOrEmpty(result)) { //Set the password as the input text. pass = result.ToSecureString(); //Get GCHandle of result. GCHandle gchandle = GCHandle.Alloc(result, GCHandleType.Pinned); //Clear it from memory and replace it with junk data. ClearIntPtr(gchandle.AddrOfPinnedObject(), result.Length * sizeof(char)); //Free GCHandle gchandle.Free(); pass.MakeReadOnly(); } } else { //Set the password to null if the user types nothing or clicks cancel. pass = null; } //To get the button click animation to show. We need to open the Microsoft.Win32.SaveFileDialog in a new thread. new System.Threading.Thread(new System.Threading.ThreadStart(delegate() { Dispatcher.Invoke(new Action(() => { //Set count. count = FilesBox.Items.Count; //Set current item. ci = ((ListBoxItem)FilesBox.Items[0]).Content.ToString(); })); //Initailize the open file dialog and title. SaveFileDialog saveFileDialog = new Microsoft.Win32.SaveFileDialog() { Title = count > 1 ? String.Format("Merging {0} File(s)", count) : String.Format("Converting {0}", ci) }; //If user clicks ok. if (saveFileDialog.ShowDialog() == true) { using (Combiner comb = new Combiner(pass)) { //Set output path. comb.Output = saveFileDialog.FileName; //Name of the file. string n = null; Stopwatch sw = new Stopwatch(); //Start stopwatch to check merge time. sw.Start(); Parallel.For(0, count, i => { SecureString tag = null; Dispatcher.Invoke(new Action(() => { var item = ((ListBoxItem)FilesBox.Items[i]); n = item.Content.ToString(); tag = (SecureString)item.Tag; })); comb.AddFile(File.ReadAllBytes(n), Combiner.ProtectPassword((SecureString)tag)); if (tag != null) { tag.Dispose(); } }); //Stop stopwatch. sw.Stop(); Debug.WriteLine("Time to merge pdfs in memory {0}", sw.Elapsed.ToString()); } } if (!String.IsNullOrEmpty(saveFileDialog.FileName)) { //Open the pdf file System.Diagnostics.Process.Start(saveFileDialog.FileName); } })).Start(); }