UWP 从 Task 更新 UI
Posted
技术标签:
【中文标题】UWP 从 Task 更新 UI【英文标题】:UWP update UI from Task 【发布时间】:2016-11-04 02:57:00 【问题描述】:我有一个应用程序,它正在检查本地网络中的网络范围(用于运行 http 服务)。
所以这意味着,我正在检查 f.e.从 10.0.0.1 到 10.0.0.255。问题来了,在 PC 上运行时速度足够,但在 Lumia 950 上运行时速度不够。所以我想在扫描期间更新 UI。
以下是问题:
此时我有几个任务 f.e. 10 - 每个任务都在扫描他的范围 f.e.任务 1 - 10.0.0.1 到 10.0.0.25 等 - 我应该使用 10 个任务还是有什么方法,.net 将如何自行解决?表现如何,f.e.如果我将使用 50 个任务?
第二个问题是,在扫描过程中,我会找到正在运行 Web 服务的 PC,但是……当找到 PC 时,我应该如何更新 UI?目前我只能在所有任务完成后才能做到..
我调用的方法是异步任务
【问题讨论】:
【参考方案1】:您可以使用任意数量的任务,系统会自动为您进行排队和执行。这是使用内置机制的优势之一
要在 UI 线程上执行代码,您可以像这样使用调度程序:
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
//UI code here
);
【讨论】:
您好,感谢您的回答.. 它似乎正在工作.. 但还有一些其他要求...例如,如果一个线程会找到服务器,我应该将它添加到 ListBox,是有什么办法可以解决吗? 很高兴听到这有帮助。您可以考虑将此标记为答案,以便其他人轻松发现。对于另一个要求,这应该是一个单独的问题。尝试并提供一些您尝试过的示例代码,以便人们知道从哪里开始提供答案。 Dispatcher 没有 RunAsync 方法? 如何防止出现:“名称调度程序在当前上下文中不存在”? 你应该写 Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () = > );【参考方案2】:要在 UI 线程上执行代码并且您只想更新属性。您可以使用 MVVM 和 ViewModel 继承类
public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected async void OnPropertyChanged([CallerMemberName] string propName = "")
await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.High,
() =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
);
Xaml 绑定的所有属性都使用单向或双向,并且在属性中使用 OnPropertyChanged();如果时间我的代码异常并说Current is null
你可以使用
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
//write your code
//in OnPropertyChanged use PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
);
如果您在用户控件或页面中编写了代码,您可以看到以下代码。
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
//UI code here
);
CoreDispatcherPriority 可以设置 Priority 但您不应该将其设置为 High ,请参阅CoreDispatcherPriority
【讨论】:
你好,看起来很有趣,我部分使用了你的方式。但问题是,从类中更新 GUI 是否好?我不认为它是干净的..也许还有另一种解决方案? 如果你绑定,它已经更新。有一些,我没有链接。 所以最后我使用了这个解决方案,它工作了link 如果你改变了属性,而你的UI没有改变。所以最后你也应该像我一样使用代码。链接(c-sharpcorner.com/UploadFile/5ef5aa/…)可以更改列表但不能更改属性。 使用 ObservableCollection 它可以在项目添加或删除时通知。【参考方案3】:我还发现了另一种更新 UI 的可能性——此时我正在通过这种方式更新进度条,但发现你可以传递其他变量..
var progress = new Progress<int>(i => _progress = i);
progress.ProgressChanged += Pr_ProgressChanged;
然后事件:
private void Pr_ProgressChanged(object sender, int e)
progressBar1.Value = progressBar1.Value + 1;
带参数的方法:
public async Task GetWebServers(IProgress<int> progress)
//your code
调用:
await Task.WhenAll(workers.Select(webServer => webServer.GetWebServers(progress))
);
【讨论】:
这在某些情况下可以工作,但要从异步任务调用 UI(可以从其他线程调用),最好使用 Dispatcher。以上是关于UWP 从 Task 更新 UI的主要内容,如果未能解决你的问题,请参考以下文章
UWP Xaml文本块数据绑定 - 即使属性已更新,UI也不会更新