SkyeBoniwell
SkyeBoniwell

Reputation: 7092

writing return value from a method of type System.Threading.Tasks.Task<string>

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

Answers (4)

tmaj
tmaj

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.

enter image description here

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

Md. Abdul Alim
Md. Abdul Alim

Reputation: 705

Change the line

string result = iAuth.GetServerVersionAsync().ToString();

to

string result = iAuth.GetServerVersionAsync().Result;

Upvotes: 0

maccettura
maccettura

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

Woj
Woj

Reputation: 833

string result = iAuth.GetServerVersionAsync().Result;

And then u can cast it to string with.

var stringResult = result.ToString();

Upvotes: 0

Related Questions