0

I've got a form with two collections for DataGridView binding.

public partial class MainForm : Form
{
    private List<MailViewModel> _mails;
    private Dictionary<int, string> _employees;

    public MainForm()
    {
        InitializeComponent();

        _mails = new();
        _employees = new();

        FillDataGridView();
    }
}

My goal is to not wait for server response to open form, avoiding outgoing requests until collections are initialized.

I wrote the following method that looks terrible, and I believe there's a right way to do it.

private void FillDataGridView()
{
    Task.Run(() =>
        {
            registerButton.Enabled = false;
            modifyButton.Enabled = false;
            deleteButton.Enabled = false;

            toolStripStatusLabel.Text = "Updating mail list...";

            _mails = GetMails().Result.ToList();
            _employees = GetEmployees().Result.ToDictionary(x => x.Key, x => x.Value);
            dataGridView.Invoke(() =>
            {
                dataGridView.DataSource = _mails
            .Select(mail => new
            {
                mail.Id,
                mail.Name,
                mail.Date,
                mail.Body,
                Addressee = mail.Addressee?.ToString(),
                Sender = mail.Sender?.ToString()
            }).ToList();
                dataGridView.Columns["Id"].Visible = false;
                toolStripStatusLabel.Text = "Ready";
                registerButton.Enabled = true;
                modifyButton.Enabled = true;
                deleteButton.Enabled = true;
            });
        });
}

public async Task<IDictionary<int, string>> GetEmployees() {...}
public async Task<IEnumerable<MailViewModel>> GetMails() {...}

I checked out this blog: https://blog.stephencleary.com/2013/01/async-oop-2-constructors.html - but I'm not sure it fits this case.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Emin_N
  • 1
  • 1
  • Mark `FillDataGridView()` async, change its return Type to `Task` and move it to the `Form.Load` event handler, mark it also `async` and `await` the method. Inside the method, await both `GetMails()` and `GetEmployees()`. No need to invoke. Possibly, pass the Control's instance to the method -- Avoid `.Result` and `Wait()` in this platform -- Not sure you need an anonymous Type out of `_mails`, or that you need to retrieve `_employees` at this time (since you're not using it in the method) – Jimi Apr 01 '23 at 16:53

1 Answers1

0

You can try Thread. As for I/O Bound operation Thread is more beneficial.

What is the difference between task and thread?