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
Why Does Integer Division in C# Return an Integer and Not a Float
Windows Service Cannot Access Network Location (Unc) Path
Error 5:Access Denied When Starting Windows Service
How to Pass Multiple Arguments in Processstartinfo
Programmatically Close Aspx Page from Code Behind
C# Foreach (Property in Object)... Is There a Simple Way of Doing This
C# - How to Loop Through a Table to Update Each Row MySQL
How to Get Cookies Info Inside of a Cookiecontainer (All of Them, Not for a Specific Domain)
Display Label Text With Line Breaks in C#
C# Double - Tostring() Formatting With Two Decimal Places But No Rounding
Generate Xml for <Govtalkmessage Xmlns="Http://Www.Govtalk.Gov.Uk/Cm/Envelope">
Ziparchive Gives Unexpected End of Data Corrupted Error
Reportviewer: Show Reports in Print Layout With Page Width Zoommode
Find Item in Observablecollection Without Using a Loop
File and Line Numbers for Errors Are Not Displaying in the Error List Unless the File Is Open
The Find Element Returns Empty String..Using Xpath Contains,Text()
Get and Post Methods With the Same Action Name in the Same Controller