private async void FillSignBtn_Click(object sender, RoutedEventArgs e)
        {
            bool success = await this.checkConnection();

            if (!success)
            {
                return;
            }

            this.tokenSource = new CancellationTokenSource();
            CancellationToken ct = this.tokenSource.Token;

            CancelBtn.IsEnabled      = true;
            SettingsGrid.IsEnabled   = false;
            OperationsGrid.IsEnabled = false;

            // The Progress<T> constructor captures our UI context, so the lambda will be run on the UI thread.
            var progress = new Progress <int>(percent =>
            {
                OperationProgress.Value = percent;
                ProgressLabel.Content   = percent + "%";
            });

            var stats = new SigningStats()
            {
                Processed = 0, Signed = 0
            };

            try {
                // signSerialNumbers is run on the thread pool.
                stats = await Task.Run(() => this.signSerialNumbers(progress, ct));

                OperationProgress.Value    = 100;
                StatusTextBlock.Text       = "Done!";
                StatusTextBlock.Foreground = this.defaultColor;
            }
            catch (OperationCanceledException) {
                StatusTextBlock.Text       = "Stopped!";
                StatusTextBlock.Foreground = this.errorColor;
            }
            catch (EmercoinWalletException ex) {
                StatusTextBlock.Text       = "Emercoin operation error";
                StatusTextBlock.Foreground = this.errorColor;
                AppUtils.ShowException(ex, this);
            }
            ProgressLabel.Content = string.Empty;

            SettingsGrid.IsEnabled   = true;
            OperationsGrid.IsEnabled = true;
            CancelBtn.IsEnabled      = false;
            this.tokenSource.Dispose();

            MessageBox.Show(
                this,
                "Total serial numbers processed: " + stats.Processed + "\n" + "Records signed: " + stats.Signed,
                AppUtils.AppName);
        }
        private SigningStats signSerialNumbers(IProgress <int> progress, CancellationToken ct)
        {
            var stats = new SigningStats();

            var signedColumns = new HashSet <int>();

            for (int n = 0; n < this.snData.HeaderRow.Length; n++)
            {
                string col = this.snData.HeaderRow[n];
                if (col.StartsWith("F-"))
                {
                    signedColumns.Add(n);
                }
            }

            int i = 0;

            foreach (string[] row in this.snData.Rows)
            {
                string sn   = row[0];
                string name = this.settings.RootDPOName + ":" + sn;

                for (int j = 0; j < 100; j++)
                {
                    string nameUnique = name + ":" + j.ToString(CultureInfo.InvariantCulture);
                    if (this.wallet.CheckNameIsMine(nameUnique))
                    {
                        var record       = string.Empty;
                        var messageParts = new List <string>()
                        {
                            nameUnique
                        };
                        for (int k = 1; k < this.snData.HeaderRow.Length; k++)
                        {
                            string part = this.snData.HeaderRow[k] + "=" + row[k];
                            record = record + part + "\n";
                            if (signedColumns.Contains(k))
                            {
                                messageParts.Add(part);
                            }
                        }

                        string signedMessage = this.wallet.SignMessage(string.Join("|", messageParts));
                        record = record + "Signature=" + signedMessage;
                        this.wallet.UpdateName(nameUnique, record, 1, this.settings.OwnerAddress);
                        stats.Signed++;
                        break;
                    }
                }
                stats.Processed++;

                if (i > 0 && i % 10 == 0)
                {
                    Thread.Sleep(5000);
                }

                i++;
                if (progress != null)
                {
                    progress.Report(getPercent(i, this.snData.Rows.Count));
                }
                ct.ThrowIfCancellationRequested();
            }

            return(stats);
        }