Reputation: 7092
I'm trying to get info from a connected service that I added to my simple c# console app.
Here is what I am running in Visual Studio:
class Program
{
static void Main(string[] args)
{
IAuth iAuth = new AuthClient();
Console.WriteLine("\nYour server version:\n ");
string result = iAuth.GetServerVersionAsync().ToString();
Console.WriteLine(result);
Console.Write("\nPress any key to continue ...");
Console.ReadKey(true);
}
}
When I run it, I don't get any errors, but I just get this returned:
Your server version:
System.Threading.Tasks.Task`1[System.String]
Press any key to continue ...
GetServerVersionAsync() is part of an API and looks like this:
public System.Threading.Tasks.Task<string> GetServerVersionAsync()
{
return base.Channel.GetServerVersionAsync();
}
How do I get it to return an usable value?
Thanks!
Upvotes: 0
Views: 2749
Reputation: 34967
While other answers show you how to make-it-work, the correct solution is to make Main async
, which is available from C♯7.1 since 2017 (see What's new in C# 7.1) .
static async Task Main(string[] args) // <-- not 'void', but 'async Task'
{
//Option 1. The best: async Task Main
IAuth iAuth = new AuthClient();
Console.WriteLine("\nYour server version:\n");
var version = await iAuth.GetServerVersionAsync(); //<---- key word 'await'
Console.WriteLine(version);
Console.Write("\nPress any key to continue ...");
Console.ReadKey(true);
}
If you get Program does not contain a static 'Main' method suitable for an entry point error you may need to set the C♯ version in project properties.
The interaction between non-async
and async
worlds is tricky, sometimes very and it should be avoided. Please see How to call asynchronous method from synchronous method in C#?
Option 2 - non-async Main
Even if you decide you don't want async Taks Main
I suggest having a helper method that is async
. I think it's a better habit to develop. From inside this helper method you can use XAsync()
methods with the await keyword, the way it's intended.
Here's an example.
static void Main(string[] args)
{
//Option 1. Not the best: void Main
//Mixing async and non-async worlds - avoid if possible.
//See https://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in-c
Task t = MyMethodAsync();
t.Wait();
}
private static async Task MyMethodAsync() {
IAuth iAuth = new AuthClient();
Console.WriteLine("\nYour server version:\n");
string version = await iAuth.GetServerVersionAsync(); //<---- key word 'await'
Console.WriteLine(version);
Console.Write("\nPress any key to continue ...");
Console.ReadKey(true);
}
Upvotes: 1
Reputation: 705
Change the line
string result = iAuth.GetServerVersionAsync().ToString();
to
string result = iAuth.GetServerVersionAsync().Result;
Upvotes: 0
Reputation: 10818
The problem here is that you never get the result of your task. To do that you need to await
the task, or to access the task's result. The latter will block your main thread until the task is complete.
If you are using C# 7.1 or higher, you can use async Main()
so you can await the task:
static async Task Main(string[] args)
{
//some code
string result = await iAuth.GetServerVersionAsync();
//Some more code
}
If you are using a version of C# lower than 7.1 you can just block the thread until your async method completes:
static void Main(string[] args)
{
//some code
string result = iAuth.GetServerVersionAsync().Result;
//Some more code
}
EDIT judging by the equal upvotes and downvotes it seems like my blurb about making GetServerVersionAsync()
async was not received as I intended. Obviously making that method async does not fix the problem, but since the method is suffixed with the word "Async" and it calls an async
method, it seemed wise to make it async
for clarity.
Upvotes: 2
Reputation: 833
string result = iAuth.GetServerVersionAsync().Result;
And then u can cast it to string with.
var stringResult = result.ToString();
Upvotes: 0