【问题标题】:What is the wrong with following async/await example? Please guide [duplicate]以下 async/await 示例有什么问题?请指导[重复]
【发布时间】:2022-01-21 17:54:23
【问题描述】:

我创建了一个 Windows 窗体 - Form1,用于理解 C# 中的 async-await,它只有两个控件:一个按钮 (btnDemo) 和一个标签 (lblRandom)。我正在使用 .NET Framework 4.0。

这是代码:

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

    private async void btnDemo_Click(object sender, EventArgs e)
    {
        Task<int> myTask = new Task<int>(GetNumber);
        myTask.Start();
        lblRandom.Text = "Getting...";
        lblRandom.Text = await myTask;
    }

    private int GetNumber()
    {
        Thread.Sleep(10000);
        return new Random().Next(1, 100);
    }
}

当我尝试运行此代码时,它显示以下错误(在await myTask 行):

Task&lt;int&gt;”不包含“GetAwaiter”的定义,并且找不到接受“Task&lt;int&gt;”类型的第一个参数的扩展方法“GetAwaiter”(您是否缺少 using 指令或程序集引用? )

有人可以帮我理解这个错误并为上述代码提供解决方案吗?

【问题讨论】:

  • 您的代码文件顶部可能缺少using System.Threading.Tasks;
  • 我看到了一个返回 Task 的方法 (GetNumber),您尝试将其结果分配给 string。如果您的所有参考资料都正确,它应该会给您另一种类型的错误。
  • 您的目标是 .NET 4.0,这是 a) 大量过时的; b) 没有适当的 async/await 支持。我强烈建议您更新您所针对的 .NET 版本。
  • @Llama:我已经检查过了,我没有错过 using 指令。
  • @Steve:即使我将赋值更改为正确的type(即int,该错误仍然保持原样......

标签: c# winforms async-await visual-studio-2015


【解决方案1】:

这可能是 winforms 中 async/await 的更好演示。在 .net framework 4.7.2 或 .net 5+ 上创建一个新的 winforms 项目。在默认的 Form1 上,在表单上放置一个计时器、两个标签、两个按钮和一个 datagridview。将它们全部保留为默认名称并将其粘贴到表单代码的顶部:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        timer1.Enabled = true;
        timer1.Tick += Timer1_Tick;
        button1.Text = "ThreadSleep";
        button2.Text = "TaskDelay";
        dataGridView1.DataSource = new List<string[]> { "a b".Split(), "c d".Split()};
    }

    private void Timer1_Tick(object sender, EventArgs e)
    {
        label1.Text = DateTime.Now.ToString();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        label2.Text = "Going to sleep for 5s";
        Thread.Sleep(5000);
        label2.Text = "I'm awake";
    }

    private async void button2_Click(object sender, EventArgs e)
    {
        label2.Text = "Delaying for 5s";
        await Task.Delay(5000);
        label2.Text = "The task is done";
    }
}

确保您在顶部有这些usings:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

运行应用程序。点击 ThreadSleep 按钮,注意 UI 卡住了 5 秒; label2 不更新,时钟不更新,不能点击datagridview 更改选择

这是因为你让 UI 线程(其工作是绘制 UI)休眠 5 秒

现在单击 TaskDelay 按钮。一切都保持活力 - 计时器滴答作响,label2 立即显示“延迟”,您仍然可以在 DGV 周围单击。这是因为 async/await 不是让 UI 线程休眠,而是让该线程在遇到await 时停止运行您的代码,并返回开始处理您的代码之前正在做的事情。任务完成后,它会返回并从中断处继续

【讨论】:

  • 是的,因为我已更改为 .NET 4.6 版,所以可以正常工作。非常感谢...!
  • 没有问题。随意单击灰色复选标记以在仪表板上将问题标记为已回答
猜你喜欢
  • 2016-07-05
  • 1970-01-01
  • 2018-11-25
  • 2020-03-25
  • 2019-03-24
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 2020-06-06
相关资源
最近更新 更多