1

I am a relative noop at C# and his is my first attempt at asynchronous methods. I've put together a simple practice app (WPF MVVM) that lists the performance counters on my system. I've spent a few hours at this point reading questions and posts found via google. According to several of them, I am doing this wrong, but I made several attempts at making the below code work better. Admittedly, I am a bit confused by a lot of the documentation and help guides, on distinguishing between async and Tasks. This guide has offered a bit of help but I'm struggling to apply it to my code.

The Code

public async void UpdateCounters(PerformanceCounterCategory category) { await Task.Run(() => { Counters = GetCounters(category); }); } private ObservableCollection<PerformanceCounter> GetCounters(PerformanceCounterCategory category) { var countersList = new ObservableCollection<PerformanceCounter>(); if(category != null) { var instances = category.GetInstanceNames().OrderBy(ins => ins); if(instances.Any()) { foreach(var instance in instances) { if(category.InstanceExists(instance)) { //this is time consuming segment when I'm listing something like "Process" counters var counters = category.GetCounters(instance); foreach(var counter in counters) countersList.Add(counter); } } } } return countersList; } 

I've tried converting the method to an async method. Like so...

private async Task<List<PerformanceCounter>> GetCounters(PerformanceCounterCategory category) { //Changes receiving expression to Counter = new ObservableCollection(GetCounters(category)); var countersList = new List<PerformanceCounter>(); //But I couldn't figure out where to put the await 

I'm ultimately wanting to display "waiting..." or some other prompt/progress indicator on the UI, but I want to do it the right way. My current codes prevents it from being non-responsive, but that's about all.

Should this all be in a single async method, possibly like I've already done with a bit better coding, or should I be creating a list of tasks in the foreach. (I took at shot that too but it was an epic failure).

2
  • 1
    @lumberajackshaw read this link as well and understand what Design-Pattern that @PranayRana has used it will help you later in case you run across different patterns in Code / Design .NET Design Patterns Commented Dec 16, 2017 at 18:11
  • updated my answer with exception handling ...for each individual task Commented Dec 16, 2017 at 18:24

1 Answer 1

1

do as below

private async Task<List<PerformanceCounter>> GetCounters(PerformanceCounterCategory category) { List<Task<PerformanceCounter>> lstTask = new List<Task<PerformanceCounter>>(); List<PerformanceCounter> counters = new List<PerformanceCounter>(); //your code foreach(var instance in instances) { lstTask.Add( Task.Factory.StartNew(()=> return category.GetCounters(instance))); } try { await Task.WhenAll(lstTask.ToArray()); } catch {} foreach(var task in lstTask ) { if(task.Status != TaskStatus.Faulted) counters.Add(task.Result); else //log error task.Exception } return counters ; } 
Sign up to request clarification or add additional context in comments.

5 Comments

Why do you have is the try/catch with the t.Wait()? also t is a Task[] not a Task,
@ScottChamberlain - thanks ..i just typing her without trying but its updated now ..just need to put try..catch around await taks ...updated sma e..thanks for pointing my mistake
@PranayRana, I'm having a bit of trouble with lstTask.Add( Task.Factory.StartNew(()=> return category.GetCounters(instance))); I took out the return, but then end up with issues converting a ...PerformanceCounter[] to ...PerformanceCounter.
@PranayRana, I think I got it after changing lstTask to List<Task<PerformanceCounter[]>>.
@lumberajackshaw - ok , dont forget to upvote/accept if it worked for you..

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.