长时间运行的任务会在事件触发后推迟顺序执行先前的代码

时间:2019-05-15 14:29:17

标签: c# events synchronization

我希望我正确地描述了问题。

在以下代码中,drive.IsReady需要一些时间才能完成。在此之前的命令是在文本框中打印文本“正在扫描驱动器...”。文字虽然会在foreach()完成后出现。

为什么会发生这种情况?我该如何在长期运行的任务之前通知用户?

public Form1()
{
    InitializeComponent();
    button1.Click += new System.EventHandler(this.Button1_Click);
}

private void Button1_Click(object sender, EventArgs e)
{
    richTextBox1.Text = "Scanning drives, please wait...";
    PopulateComboBox();
}

void PopulateComboBox()
{
    System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();

    foreach (System.IO.DriveInfo drive in drives)
    {
        if (drive.IsReady)
        {
            comboBox1.Items.Add(drive.Name + drive.VolumeLabel);
        }
        else
        {
            comboBox1.Items.Add(drive.Name);
        }
    }            
}

1 个答案:

答案 0 :(得分:1)

这些是使代码的慢速部分(drive.IsReady)异步运行所需的最小更改。它不会运行得更快,其目的只是保持用户界面的响应速度。

private async void Button1_Click(object sender, EventArgs e) // + async
{
    richTextBox1.Text = "Scanning drives, please wait...";
    await PopulateComboBox(); // + await
}

async Task PopulateComboBox() // async Task instead of void
{
    System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();

    foreach (System.IO.DriveInfo drive in drives)
    {
        if (await Task.Run(() => drive.IsReady)) // + await Task.Run(() => ...)
        {
            comboBox1.Items.Add(drive.Name + drive.VolumeLabel);
        }
        else
        {
            comboBox1.Items.Add(drive.Name);
        }
    }            
}