How to Get Bool Result from Async Task<Bool> Function in C# - Error: Cannot Implicitly Convert Type 'Void' to 'Bool'

How to get bool result from async task<bool> function in C# - Error: Cannot implicitly convert type `void' to `bool'

Statement 1. .Wait() has no return result. It is a void method, and therefore its result cannot be assigned to a variable.

You can use .Result which will wait until Task completes and return a result.

// Both are applicable to simple Tasks:
bool isValid = MyValidationFunction(jsonData).Result;

// does that same as

var task = MyValidationFunction(jsonData);
task.Wait();
bool isValid = task.Result;

However, it is all valid for usual Tasks, but not for async/await functionality, because...

Statement 2. Do not mix up async and .Wait() - it still blocks the thread, killing the idea of async/await and negating all the performance improvement.

It also causes deadlock in WinForms, WPF, ASP.NET and other environments with SynchronizationContext.
Read more about it in this Stephen Cleary's article or in these StackOverflow questions:

  • An async/await example that causes a deadlock
  • await works but calling task.Result hangs/deadlocks

Simple rule: if you use async, then you use await.

// That's how you do it with async/await:
public async bool GetJsonAndValidate()
{
string jsonData = GetJson();
bool isValid = await MyValidationFunction(jsonData);
}

It will not block the thread and enable asynchronous behavior.

Cannot implicitly convert type 'void' to 'bool' Xamarin alert

Your calling the overload that returns void, see Display Alert Void and Display Alert Bool You'll need to supply the parameter string accept to get the proper overload.

Cannot implicitly convert type 'bool' to 'system.threading.tasks.task bool'

You need to be specific whether you want this operation happen asynchronously or not.

As an example for Async Operation :

public async Task<bool> login(string usn, string pwd)
{
DataClasses1DataContext auth = new DataClasses1DataContext();
var message = await (from p in auth.Users
where p.usrName == usn && p.usrPass == pwd
select p);
if (message.Count() > 0)
{
return true;
}
else
{
return false;
}
}

If you don't need it to be an Async operation, try this:

public bool login(string usn, string pwd)
{
DataClasses1DataContext auth = new DataClasses1DataContext();
var message = from p in auth.Users
where p.usrName == usn && p.usrPass == pwd
select p;
if (message.Count() > 0)
{
return true;
}
else
{
return false;
}
}

Note:
async and await are compatible with .net 4.5 and C# 5.0 and more

Async Task wont return to my task run call class

Chances are you are experiencing dead-lock. For the fun of it, try doing this

var result = await Task.Run(() => SolveCaptcha(imagename)).ConfigureAwait(false);

instead of what you are currently doing in your login method.

The other thing I noticed, is SolveCaptcha() is already asynchronus, so you don't need the Task.Run() wrapper. Typically you use Task.Run() wrapper for CPU-bound work (think heavy processing like hashing, encryption, etc.) not I/O work (like reading from a socket or file.)

So in the end, it should look like this:

await SolveCaptcha(imagename).ConfigureAwait(false);

One more issue the should be corrected is your method that contains this line. You have it as async void, but it should be async Task. The caller will need a Task to await on and examine.

As far as how this dead-lock happens... there is plenty of information on it. Just google c# async/await configureawait deadlock. Here is some more information to get you started (somewhere in the middle of the page, search for the word "deadlock" in bold)

cannot convert from threading task<bool> to system action

public async Task MainAsync

should be changed to

public async Task<bool> MainAsync

And then instead of

var result = await Task.Run( MainAsync("", "", "", "", "", "")).GetAwaiter().GetResult();

you can use

var result = await MainAsync("", "", "", "", "", "");

Also you need to use async in the following line too:

var logoutResult = Task.Run(() => _instaApi.LogoutAsync()).GetAwaiter().GetResult();

Becomes:

var logoutResult = await _instaApi.LogoutAsync();

Why does an bool out variable get cleared when i return?

out bool fileexists declares a new variable called fileexists, which "hides" the global variable as long as the new variable is in scope.

If you want to refer to an existing variable or field, use out fileexists (without the data type) instead:

if (HelperClass.CheckFileExists(filename, out fileexists)) ...

As a side note, it looks like you don't need an out parameter in this case: If your helper method does what its name suggests, the following code:

fileexists = HelperClass.CheckFileExists(filename);
if (fileexists) ...

might be more readable and avoids returning the same value both as a return value and as an out parameter.

Cannot implicitly convert type bool to System.Threading.Tasks.Task<bool>

According to the error, this returns a bool:

CC.MethodThatReturnsBool()

So you'd store it as such:

bool newBool = CC.MethodThatReturnsBool();

Which, it would seem, means that there are no asynchronous operations to be awaited. Simplifying:

public void Starter()
{
CC = new CustomClass();

bool b = CC.MethodThatReturnsBool();

// do something with your bool?
}

It's not clear why you're expecting to await anything, and there may indeed be more to this that you're not showing, but if the method you're calling is synchronous then there's no need to await it.

Side note: async void is a really bad idea. It only exists for compatibility with UI event handlers and such. If you're writing anything that you control, don't use async void.


Edit:

Based on your update to the question, it sounds like what's happening here is that you have a long-running synchronous process that you'd like to not block the UI thread? You can wrap something in a Task, perhaps something like this:

bool b = await Task.Run(() => new CustomClass().MethodThatReturnsBool());

So perhaps overall you're looking for something more like this (untested)?:

public async Task Starter()
{
Task<bool> newTask = Task.Run(() => new CustomClass().MethodThatReturnsBool());

// DO SOME VISUAL THINGS

bool b = await newTask;

// do something with your bool?
}

To elaborate on a previous point, note that the overall method is now async Task instead of async void. This makes Starter itself awaitable, as void otherwise would not be.

Ideally of course, MethodThatReturnsBool should itself be async if it is internally performing various I/O bound operations which cause its delay. (As implied in your comment on the question above.) That may involve refactoring elsewhere in the system, but in the long run is the preferable approach.



Related Topics



Leave a reply



Submit