【问题标题】:UWP update UI from TaskUWP 从 Task 更新 UI
【发布时间】:2016-11-04 02:57:00
【问题描述】:

我有一个应用程序,它正在检查本地网络中的网络范围(用于运行 http 服务)。

所以这意味着,我正在检查 f.e.从 10.0.0.1 到 10.0.0.255。问题来了,在 PC 上运行时速度足够,但在 Lumia 950 上运行时速度不够。所以我想在扫描期间更新 UI。

以下是问题:

  1. 此时我有几个任务 f.e. 10 - 每个任务都在扫描他的范围 f.e.任务 1 - 10.0.0.1 到 10.0.0.25 等 - 我应该使用 10 个任务还是有什么方法,.net 将如何自行解决?表现如何,f.e.如果我将使用 50 个任务?

  2. 第二个问题是,在扫描过程中,我会找到正在运行 Web 服务的 PC,但是……当找到 PC 时,我应该如何更新 UI?目前我只能在所有任务完成后才能做到..

我调用的方法是异步任务

【问题讨论】:

    标签: c# user-interface task uwp


    【解决方案1】:
    1. 您可以使用任意数量的任务,系统会自动为您进行排队和执行。这是使用内置机制的优势之一

    2. 要在 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。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    • 2019-04-27
    • 2016-12-17
    • 2018-09-05
    相关资源
    最近更新 更多