20

I have application, which is checking network ranges (for running http service) in local network.

So it means, that I am checking f.e. from 10.0.0.1 to 10.0.0.255. And here is the problem, when running on PC, the speed is enough, but when running on Lumia 950 the speed is not enough. So I would like to update the UI during the scan.

So here are the questions:

  1. At this moment I have several tasks f.e. 10 - every task is scanning his range f.e. task 1 - 10.0.0.1 to 10.0.0.25 etc.. - should I use 10 tasks or is there some way, how the .net will solve it itself? What will be the performance, f.e. if I will use 50 tasks?

  2. Second question is, during the scan I will find the PC, where the web service is working, but... How should I update the UI when the PC is found? At this moment I am only able to do it, when all tasks are finished..

The methods I am calling are async Tasks

DotNetRussell
  • 9,716
  • 10
  • 56
  • 111
petrtim
  • 267
  • 1
  • 2
  • 10

3 Answers3

52
  1. You can use as many tasks as you want, the system will automatically perform queuing and execution for you. That's one of the advantages of using the built in mechanisms

  2. To execute code on the UI thread you can use the dispatcher like this:

    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => {
                //UI code here
    });
    
AlexDrenea
  • 7,981
  • 1
  • 32
  • 49
  • Hello, thanks for answers.. It seems to be working.. But have some other requirements... for example if one thread will find the the server, I should add it to the ListBox, is there some way how to solve it? – petrtim Jul 01 '16 at 19:25
  • Glad to hear this helped. You might consider marking this as answer so it's easily discovered by others. For the other requirement, that should be a separate question. Try and provide some sample code of what you have tried so that people know where to start to provide an answer. – AlexDrenea Jul 01 '16 at 19:33
  • 1
    Dispatcher has no RunAsync method? – ShrimpCrackers Apr 25 '17 at 05:33
  • How do you prevent getting: “The name dispatcher does not exist in the current context” ? – Doug Null Dec 04 '18 at 18:02
  • 1
    You should write Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () = > {}); – Luis Alves Dec 26 '18 at 15:52
22

To execute code on the UI thread and you only want to update the property .You can use MVVM and the ViewModel inheritance the class

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));
           });
   }
}

And all the property the Xaml bind use oneway or twoway and in the property use OnPropertyChanged(); And if the time my code expception and say that Current is null

You can use

await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => 
{
     //write your code
     //in OnPropertyChanged use PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
});

If you wrote the code in user control or a page that you can see the below code.

await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => 
{
            //UI code here
});

The CoreDispatcherPriority can set Priority but you shouldnt set it to High ,see CoreDispatcherPriority

lindexi
  • 4,182
  • 3
  • 19
  • 65
  • Hello, seems interesting, I used you way partly. But the question is, is it good, that the GUI is updated from the class? I do not think that it is clean.. maybe there is another solution? – petrtim Jul 04 '16 at 17:46
  • If you bind,it's updated.There have some ,I don't have the link. – lindexi Jul 05 '16 at 02:10
  • So at the end I used this solution and it worked [link](http://www.c-sharpcorner.com/UploadFile/5ef5aa/binding-collection-to-listview-control-in-uwp-explained/) – petrtim Jul 05 '16 at 14:11
  • If you make the property change ,and your UI have not change.So at the end you also should use the code like me.The link(http://www.c-sharpcorner.com/UploadFile/5ef5aa/binding-collection-to-listview-control-in-uwp-explained/) can change the list but not property. – lindexi Jul 06 '16 at 00:12
  • Yes, but in my case, the property is List so the event if something will be added to the list will not be fired.. – petrtim Jul 06 '16 at 08:37
  • 1
    Use ObservableCollection it can notify when the item add or remove. – lindexi Jul 08 '16 at 06:22
-2

I also found another possibility how to update the UI - at this moment I am updating progress bar by this way, but found you can pass other variables..

 var progress = new Progress<int>(i => _progress = i);
 progress.ProgressChanged += Pr_ProgressChanged;

then event:

  private void Pr_ProgressChanged(object sender, int e)
    {
        progressBar1.Value = progressBar1.Value + 1;
    }

Method with parametrs:

 public async Task GetWebServers(IProgress<int> progress) {
 //your code
}

Calling:

await Task.WhenAll(workers.Select(webServer => webServer.GetWebServers(progress))
       );
petrtim
  • 267
  • 1
  • 2
  • 10
  • 1
    This can work in some case, but to call UI from an async task (can be called from an other thread) it's better to use Dispatcher. – Benoit Mar 10 '19 at 18:37