仅在异步任务完成后显示表格

时间:2018-06-25 10:48:37

标签: c# multithreading asynchronous

我有以下自定义Task代码:

public static async Task Run(this CustomForm parent, Action action)
{
    parent.Enabled = false;
    using (Caricamento form = new Caricamento())
    {
        form.TopLevel = true;
        form.TopMost = true;
        form.Show();
        await Task.Run(action);
    }
    parent.Enabled = true;
}

async任务完成之前,无法正确加载gif动画和表单中的文本。

    ListMessaggi listForm = new ListMessaggi(ListMessaggi.Tipo.Entrata);
    listForm.FormClosing += (o, args) =>
    {
        if (this.Controls.Count == 2)
        {
            args.Cancel = true;
        }
    };

    listForm.FormBorderStyle = FormBorderStyle.None;
    listForm.Dock = DockStyle.Fill;
    listForm.TopLevel = false;
    panel.Controls.Add(listForm);
    listForm.Show();

然后,以显示listForm.Show()方法调用的形式显示:enter image description here

最后,该结果在异步任务运行时显示: enter image description here

如何改进代码以使事情正常运行?

1 个答案:

答案 0 :(得分:1)

根据您在注释中提供的其他信息,我认为您应该尝试将代码转换为完全使用async / await。这将涉及将所有ADO.NET函数转换为.NET 4.5中添加到ADO的新async methods。这将消除所有的Task.Run调用,以及为将控制权调回UI线程而进行的混乱的InvokeRequiredBeginInvoke调用。

我认为您会发现,如果实施正确,您甚至不需要特殊的Run扩展方法;您将可以在线插入所有代码,就像在“传统” .net开发中一样。

例如,您可以使用这样的代码在表单的Load事件中以响应方式加载数据,而无需锁定UI。

public async void Form1_Load(object sender, EventArgs e)
{
    var data = await _dataProvider.GetSomeDataFromTheDatabase(aTotallyMadeUpVariable);
    this.MyDataGrid.DataSource = data;
}

完全相同的模式适用于组合框和按钮上的事件处理程序。


请注意,WinForms中的事件处理程序实际上是async void方法合法有效的唯一位置。其他所有内容,包括从内部事件处理程序调用的async方法,都应为Task返回函数。


async / await上多了一些“入门”,这就是它避免在上面的示例中阻塞UI线程的方式。

函数上的async修饰符充当编译器的标记,以将方法转换为状态机。编译将对方法中的代码进行分段,并在每次await调用时将其分解为单独的状态。调用函数时,将运行第一个状态(直至await所在的位置),然后函数返回到调用方。当正在等待的函数返回时,其后的代码(在下一个状态中)将作为继续调用。在状态之间共享的所有数据(例如局部变量)都移到一个对象中,该对象传递到每个状态的延续中。