【问题标题】:How can change the value of a UI element property from an asynchronous method? [duplicate]如何从异步方法更改 UI 元素属性的值? [复制]
【发布时间】:2021-09-04 03:31:07
【问题描述】:

我正在尝试学习异步编程 (C#/WPF),但我似乎无法理解一些东西,所以我从一个更简单的示例开始,但我仍然卡住了。

示例:在文本框中添加 2 行文本,并在按下按钮时显示所用时间。

这是代码:

private async void b1_Click(object sender, RoutedEventArgs e)
{
    txtb1.Text = "";

    var watch = System.Diagnostics.Stopwatch.StartNew();

    await writeintxtbx();

    watch.Stop();
    var elapsedtm = watch.ElapsedMilliseconds;

    txtb1.Text += $"TOTAL TIME {elapsedtm} \n\n\n";
}

private async Task writeintxtbx()        
{
   await Task.Run(() => Task1());
   await Task.Run(() => Task2());
}

private void Task1() 
{
    txtb1.Text += $"Task 01 Done \n\n";
}

private void Task2() 
{
    txtb1.Text += $"Task 2 done \n\n";
}

这是我得到的错误:

]]1

【问题讨论】:

标签: c# .net wpf asynchronous async-await


【解决方案1】:

UI 元素(在表单和 WPF 中)仅允许您在创建它们的同一线程上使用它们自己。
默认情况下,这是应用程序的主线程。
WPF 中的每个 UI 元素(在 Forms 中有些不同)都有一个 Dispatcher 属性,该属性提供了一个线程管理器,您可以从中与该 UI 元素进行交互。
由于您使用的是异步方法,因此您需要使用如下代码来引用其中的 UI 元素:

private DispatcherOperation Task1() 
{
    return txtb1.Dispatcher.BeginInvoke(() => txtb1.Text += $"Task 01 Done \n\n");
}

但最好使用绑定来处理 WPF。
binding-source 属性的值可以在任何线程上更改。 这极大地促进了数据和 UI 元素之间的交互。 这是 WPF 的功能之一。
如果 WPF 解决方案是 MVVM 模式的实现,则以最佳方式使用 WPF 解决方案的所有功能、工具和优势。

【讨论】:

    猜你喜欢
    • 2019-12-16
    • 1970-01-01
    • 2017-11-11
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 2013-11-30
    相关资源
    最近更新 更多