将用户控件添加到网格异步[重复]
Posted
技术标签:
【中文标题】将用户控件添加到网格异步[重复]【英文标题】:Adding UserControls to Grid Asynchronously [duplicate] 【发布时间】:2021-09-15 12:13:02 【问题描述】:我正在使用 WPF 应用程序,并且在应用导航时遇到问题,屏幕冻结,所以我想实现异步
我的导航方法:我创建一个网格并将用户控件添加到该网格的 children 属性 由于我在许多不同的用户控件上有这么多 UI 元素,它会冻结应用程序
我想在加载窗口时添加一个异步用户控件,我的想法是使用 async await 关键字,但显然我使用错误,我研究过,不明白为什么建议使用调度程序甚至在有异步等待之后,所以我想按照这种方式(异步/等待)
这只是真实交易的一个示例问题
这是代码
private async void grid1_Loaded(object sender, RoutedEventArgs e)
txtb1.Text = "";
var watch = System.Diagnostics.Stopwatch.StartNew();
await gy();
watch.Stop();
var elapsedtm = watch.ElapsedMilliseconds;
txtb1.Text += $"TOTAL TIME elapsedtm \n\n\n";
private async Task gy()
////////////
Y1 child1 = new Y1();
await Task.Run(() => grid1.Children.Add(child1));
///////////
【问题讨论】:
您只能在创建 grid1 的线程中访问grid1.Children
,即不能从任务操作中访问。也许使用 DispatcherTimer 在块中添加子元素。
通常向 UI 添加元素很快。通常是一些需要时间的数据处理。或者您是说您正在创建一些 UI 元素,而数据处理可以忽略不计,这会降低您的应用程序的速度?
@Clemens 那么你是说使用 Async 和 await 是行不通的,而 dispathcher.begininvoke 就是这样,我知道如何使用 Dispatcher 执行它们我想学习异步方式
@Enigmativity 好吧,我正在使用一个名为 MaterialDesignforXAML 的库,我在用户控件中使用这些 UI 元素,并将这些用户控件添加到网格中,在添加了这些众多的用户控件之后,我只是根据几个按钮点击事件
不,我不是这么说的。 Async/await 和 Dispatcher 不是相互排斥的。两者都可以很好地协同工作。如果您要访问具有线程关联性的对象 - 例如UI 元素 - 从创建它的线程以外的线程,您必须通过对象的 Dispatcher 或在同一线程中创建的 Progress 实例来执行此操作。请注意,Task.Run 通常在与线程池不同的线程上运行。
【参考方案1】:
private async void grid1_Loaded(object sender, RoutedEventArgs e)
txtb1.Text = "";
var watch = System.Diagnostics.Stopwatch.StartNew();
//Asynchronous execution of the "gy" method in the UI thread.
await Dispatcher.InvokeAsync(gy);
watch.Stop();
var elapsedtm = watch.ElapsedMilliseconds;
txtb1.Text += $"TOTAL TIME elapsedtm \n\n\n";
// This method can only be called on the main UI thread.
private void gy()
////////////
UIElement child1 = new Y1();
grid1.Children.Add(child1);
///////////
如果 gy 方法中有一些长期操作不使用 UI 元素,并且您需要将主 UI 线程从它们的执行中释放出来,那么这个选项:
private async void grid1_Loaded(object sender, RoutedEventArgs e)
txtb1.Text = "";
var watch = System.Diagnostics.Stopwatch.StartNew();
await gy();
watch.Stop();
var elapsedtm = watch.ElapsedMilliseconds;
txtb1.Text += $"TOTAL TIME elapsedtm \n\n\n";
private async Task gy()
// Here's some lengthy code, but in which there are no calls to UI elements.
////////////
await grid1.Dispatcher.BeginInvoke(new Action(() =>
UIElement child1 = new Label() Content = "Hello" ;
grid1.Children.Add(child1);
));
///////////
// Here's some lengthy code, but in which there are no calls to UI elements.
【讨论】:
以上是关于将用户控件添加到网格异步[重复]的主要内容,如果未能解决你的问题,请参考以下文章
将内容编辑器 Web 部件添加到 sharepoint 2010 用户控件