在 WinForms 上使用 async/await 访问 Task.Run 中的 UI 控件 [英] Accessing UI controls in Task.Run with async/await on WinForms

查看:41
本文介绍了在 WinForms 上使用 async/await 访问 Task.Run 中的 UI 控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个带有一个按钮和一个标签的 WinForms 应用程序中有以下代码:

I have the following code in a WinForms application with one button and one label:

using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            await Run();
        }

        private async Task Run()
        {
            await Task.Run(async () => {
                await File.AppendText("temp.dat").WriteAsync("a");
                label1.Text = "test";
            });    
        }
    }
}

这是我正在开发的真实应用程序的简化版本.我的印象是通过在我的 Task.Run 中使用 async/await,我可以设置 label1.Text 属性.但是,在运行此代码时,我收到错误消息,即我不在 UI 线程上并且无法访问控件.

This is a simplified version of the real application I'm working on. I was under the impression that by using async/await in my Task.Run I could set the label1.Text property. However, when running this code I get the error that I'm not on the UI thread and I can't access the control.

为什么我无法访问标签控件?

Why can't I access the label control?

推荐答案

当你使用 Task.Run() 时,你是在说你想要在当前上下文上运行的代码,这正是发生的事情.

When you use Task.Run(), you're saing that you don't want the code to run on the current context, so that's exactly what happens.

但是没有必要在您的代码中使用 Task.Run().正确编写的 async 方法不会阻塞当前线程,因此您可以直接从 UI 线程使用它们.如果这样做,await 将确保该方法在 UI 线程上恢复.

But there is no need to use Task.Run() in your code. Correctly written async methods won't block the current thread, so you can use them from the UI thread directly. If you do that, await will make sure the method resumes back on the UI thread.

这意味着如果你像这样编写代码,它会起作用:

This means that if you write your code like this, it will work:

private async void button1_Click(object sender, EventArgs e)
{
    await Run();
}

private async Task Run()
{
    await File.AppendText("temp.dat").WriteAsync("a");
    label1.Text = "test";
}

这篇关于在 WinForms 上使用 async/await 访问 Task.Run 中的 UI 控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆