Resolved Cancel the execution of the program when user closes the form

Anonymous

Well-known member
Joined
Sep 29, 2020
Messages
94
Programming Experience
Beginner
I am writing a winform application that reads a large excel file, does some processing, and writes output in some other excel file. While the main form is doing its task, my app shows a please wait form. I want to implement a functionality when if the user clicks on the cross sign of the pleasewait form, he should be prompted if he really wishes to exit, if he clicks yes, then the application should stop executing.


Here is my code :

C#:
private async Task btnClick()
{
    try
    {
        cts = new CancellationTokenSource();

        PleaseWait pleasewait = new PleaseWait();
        pleasewait.Closed += PleaseWait_Closed;
       
        pleasewait.Show();

        // Perform your long-running task asynchronously
        await Task.Run(() => ProcessBookstoreExcel(cts.Token));

        pleasewait.Closed -= PleaseWait_Closed;

        pleasewait.Close();
        MessageBox.Show("Processing Complete!");
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    finally
    {
        cts.Dispose();

        cts = null;
    }
}

private void PleaseWait_Closed(object sender, EventArgs e) => cts.Cancel();

private void ProcessBookstoreExcel(CancellationToken cancellationToken)
{
    string path = TxtBox.Text;
    ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
    var records = new List<BookRecord>();

    using (var package = new ExcelPackage(new FileInfo(path)))
    {
        ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
        int rowCount = worksheet.Dimension.Rows;

        for (int row = 2; row <= rowCount; row++) // Skip header row
        {
            cancellationToken.ThrowIfCancellation();

            records.Add(new BookRecord
            {
                LineNumber = row,
                ISBN = worksheet.Cells[row, 1].Text,
                Title = worksheet.Cells[row, 2].Text,
                Stock = int.Parse(worksheet.Cells[row, 3].Text),
                Price = decimal.Parse(worksheet.Cells[row, 4].Text),
                PublisherID = int.Parse(worksheet.Cells[row, 5].Text),
                PublisherName = worksheet.Cells[row, 6].Text
            });
        }
    }

    var discrepancies = new List<Discrepancy>();
    var groupedRecords = new Dictionary<string, Dictionary<string, (decimal Price, int Stock)>>();

    foreach (var record in records)
    {
        cancellationToken.ThrowIfCancellation();
       
        var publisherKey = record.PublisherID.ToString();
        var isbnKey = record.ISBN;

        if (!groupedRecords.ContainsKey(publisherKey))
        {
            groupedRecords[publisherKey] = new Dictionary<string, (decimal Price, int Stock)>();
        }

        if (!groupedRecords[publisherKey].ContainsKey(isbnKey))
        {
            groupedRecords[publisherKey][isbnKey] = (record.Price, record.Stock);
        }
        else
        {
            var existing = groupedRecords[publisherKey][isbnKey];
            if (existing.Price != record.Price || existing.Stock != record.Stock)
            {
                discrepancies.Add(new Discrepancy
                {
                    LineNumber = record.LineNumber,
                    Publisher = record.PublisherName,
                    Title = record.Title
                });
            }
        }
    }

    WriteDiscrepancies(discrepancies);
    MessageBox.Show("Processing complete. Check the output file for discrepancies.");
}

private void WriteDiscrepancies(List<Discrepancy> discrepancies)
{
    var outputPath = Path.Combine(Path.GetDirectoryName(filePath), "discrepancies.xlsx");

    using (var package = new ExcelPackage())
    {
        var worksheet = package.Workbook.Worksheets.Add("Discrepancies");
        worksheet.Cells[1, 1].Value = "LineNumber";
        worksheet.Cells[1, 2].Value = "Publisher";
        worksheet.Cells[1, 3].Value = "Title";

        for (int i = 0; i < discrepancies.Count; i++)
        {
            worksheet.Cells[i + 2, 1].Value = discrepancies[i].LineNumber;
            worksheet.Cells[i + 2, 2].Value = discrepancies[i].Publisher;
            worksheet.Cells[i + 2, 3].Value = discrepancies[i].Title;
        }

        package.SaveAs(new FileInfo(outputPath));
    }
}


pleasewait.cs code

C#:
private void PleaseWait_FormClosing(object sender, FormClosingEventArgs e)
{
    var x = MessageBox.Show("Are you sure you want to really exit ? ",
                            "Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

    if (x == DialogResult.No)
    {
        e.Cancel = true;
    }
    else
    {

        e.Cancel = false;
    }
}


There is one issue that I am facing at PleaseWait.Close() in the ButtonClick(). When the control is reaching there and closing the form it is showing me the dialog box "Are you Sure...". It is only working when I do PleaseWait.Hide().
 
Last edited:
This can be done with an event. The following is a basic sample. Replace Dialogs.Question with MessageBox or use it, source.

Work in progress form:
public partial class PleaseWaitForm : Form
{
    public delegate void OnCancel(bool cancel);
    public event OnCancel CancelEvent;
    public PleaseWaitForm()
    {
        InitializeComponent();
        FormClosing += PleaseWaitForm_FormClosing;
    }

    private void PleaseWaitForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (e.CloseReason != CloseReason.UserClosing) return;
        if (Dialogs.Question(this, "Are you sure you want to really exit ?"))
        {
            e.Cancel = false;
            CancelEvent?.Invoke(true);
        }
        else
        {
            e.Cancel = true;
        }
    }
}

Mock up for using above, void of actual work.

C#:
private void PerformWorkButton_Click(object sender, EventArgs e)
{
    var waitForm = new PleaseWaitForm();
    waitForm.CancelEvent += WaitForm_CancelEvent;
    waitForm.Show();
}

private void WaitForm_CancelEvent(bool cancel)
{
    if (cancel)
    {
        // user decided to cancel
    }
    else
    {
        // user decided to continue
    }
}
 
Back
Top Bottom