1
private async Task<List<PingReply>> PingAsync()
{
    Ping pingSender = new Ping();
    var tasks = serverNames.Select(ip => pingSender.SendPingAsync(ip, 2000));
    var results = await Task.WhenAll(tasks);

    return results.ToList();
}

My question is how would I execute this method?

I've tried

 List<string> data = PingAsync();

But I get this error message

Error   CS0029  Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Collections.Generic.List<System.Net.NetworkInformation.PingReply>>' to 'System.Collections.Generic.List<string>' ServerManager   

I am trying to ping servers and update the UI so we can monitor servers.

I've also tried these

        Task<PingReply> longRunningTask = PingAsync();
        PingReply result = await longRunningTask;

Error

Severity Code Description Project File Line Suppression State Error CS4033 The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'. ServerManager

Severity Code Description Project File Line Suppression State Error CS0029 Cannot implicitly convert type 'System.Threading.Tasks.Task>' to 'System.Threading.Tasks.Task' ServerManager

software is fun
  • 7,286
  • 18
  • 71
  • 129
  • 8
    You need to await that method `List data = await PingAsync();` – DavidG Dec 11 '15 at 13:43
  • 3
    I think you should try to understand the error message because as written this cannot possibly work. You will need to understand this sooner or later anyway. – usr Dec 11 '15 at 13:48
  • You might find this useful https://msdn.microsoft.com/en-us/library/hh191443.aspx – Allan Elder Dec 11 '15 at 13:51

3 Answers3

4

Look at your PingAsync method signature. What does it return? Task<List<PingReply>>. Adding async keyword does not change that type, let's say that it basically allows you to use await inside the method.

So, by calling PingAsync, you get an object of type Task<List<PingReply>>, and try to assign it to a List<string> reference - which gives you a type mismatch error.

But, you might ask, how to get an actual T form Task<T>? You should simply use await, just like you do inside your method where you call Task.WhenAll.

List<PingReply> data = await PingAsync();

pmbanka
  • 1,902
  • 17
  • 24
  • Thank you for the insight. But if I am executing from a private void method, I get an error saying "await" operatior can only be used within an asyn method – software is fun Dec 11 '15 at 13:58
  • `async` might be sometimes confusing... basically, you should never use `async void` methods (with an exception for event handlers). So, you should most probably change your `async void fooAsync()` to `async Task fooAsync()`. – pmbanka Dec 11 '15 at 14:01
  • Could he also do ``data = PingAsync().Result;`` Why/why not? What would be the difference to using await? – codeape Dec 11 '15 at 15:18
  • @codeape See http://stackoverflow.com/questions/27464287/what-is-the-difference-betweek-await-taskt-and-taskt-result – pmbanka Dec 11 '15 at 15:26
  • I did that data = PingAsync().Result and the app crashes saying ArguementException was unhandled. The inner message says "{"Value cannot be null.\r\nParameter name: source"}" – software is fun Dec 11 '15 at 17:12
1

The error message by itself is pretty clear. The method signature returns a Task<List<PingReply>>, yet for some reason you expect it to return a List<string> or Task<PingReply>, not sure why.

You should note that starting using async in your code makes it spread like a plague. This means that higher level methods calling async methods will usually need themselves be async and return a Task or Task<T>.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
0

Given this Async function

private async Task<List<PingReply>> PingAsync()
{
    Ping pingSender = new Ping();
    var tasks = serverNames.Select(
            ip => pingSender.SendPingAsync(ip, 2000)
    );
    var results = await Task.WhenAll(tasks);
    return results.ToList();
}

From some other part of the object, call, accepting the TASK wrapped value

 Task<List<PingReply>> foo = PingAsync();

Then Manually wait it out ...

foo.Wait();

Then Extract the Value

List<PingReply> bar = foo.Result;
Sean Munson
  • 343
  • 2
  • 9