在Task中返回true或false的异步方法
本文关键字:false 异步方法 true Task 返回 | 更新日期: 2023-09-27 18:03:27
我知道async
方法只能返回void
或Task
。我已经阅读了async
方法内部异常处理的类似方法。我是async
编程的新手,所以我正在寻找一个简单的解决方案。
我的async
方法运行Sql查询。如果查询正常,它应该用布尔值true
和false
通知调用者。我的方法目前是一个void,所以我没有办法知道。
private async void RefreshContacts()
{
Task refresh = Task.Run(() =>
{
try
{
// run the query
}
catch { }
}
);
await refresh;
}
我只是想将async
更改为Task
,以便在我的catch
语句中该方法将返回false
,否则将返回true
。
听起来你只需要返回一个Task<bool>
然后:
private async Task<bool> RefreshContactsAsync()
{
try
{
...
}
catch // TODO: Catch more specific exceptions
{
return false;
}
...
return true;
}
我个人不会捕捉异常,而是让调用者检查任务的错误状态,但这是另一回事。
修改方法签名为Task<bool>
。然后,如果你的方法被声明为异步,你可以简单地返回一个bool值。但正如jon skeet所说,还有其他可能更好的方法来处理您的场景
private async Task<bool> RefreshContacts()
{
Task refresh = Task.Run(() =>
{
try
{
// run the query
return true;
}
catch { return false;}
}
PS:你可能会遇到的另一个常见问题是如果你有一个没有async的方法。然后你可以像这样返回Task.FromResult(true)
:
private Task<bool> RefreshContacts()
{
....
return Task.FromResult(true)
}
对不起,但我认为你们在这里误导了人们。请看微软的文章,在这里。
非常简单的例子,展示了如何从Task返回bool
, int
或string
类型的(标量)值。
我把c#代码贴在这里,为了子孙后代:
using System;
using System.Linq;
using System.Threading.Tasks;
public class Example
{
public static void Main()
{
Console.WriteLine(ShowTodaysInfo().Result);
}
private static async Task<string> ShowTodaysInfo()
{
string ret = $"Today is {DateTime.Today:D}'n" +
"Today's hours of leisure: " +
$"{await GetLeisureHours()}";
return ret;
}
static async Task<int> GetLeisureHours()
{
// Task.FromResult is a placeholder for actual work that returns a string.
var today = await Task.FromResult<string>(DateTime.Now.DayOfWeek.ToString());
// The method then can process the result in some way.
int leisureHours;
if (today.First() == 'S')
leisureHours = 16;
else
leisureHours = 5;
return leisureHours;
}
}
// The example displays output like the following:
// Today is Wednesday, May 24, 2017
// Today's hours of leisure: 5
// </Snippet >
似乎您正在尝试为同步方法公开异步包装器。不建议这样做,您可以在这里阅读原因:我应该为同步方法公开异步包装器吗?
如果你仍然坚持这样做,可以这样做:
private Task<bool> RefreshContactsAsync()
{
return Task.Run(() =>
{
try
{
// Run the query
return true;
}
catch
{
return false;
}
});
}
注意没有async
和await
关键字。我们只使用Task.Run
重载,它接受一个Func<TResult>
形参,并返回一个Task<TResult>
。本例中的TResult
类型为bool
。
你应该怎么做呢?只需使您的RefreshContacts
方法同步:
private bool RefreshContacts()
{
try
{
// Run the query
return true;
}
catch
{
return false;
}
}
…并在调用站点用Task.Run
封装:
bool success = await Task.Run(() => RefreshContacts());
这样没有人会得到错误的印象,他们正在调用一个真正的异步方法(一个不在线程上运行的方法)。目的很明确:将同步方法卸载到ThreadPool
,很可能是为了保持UI的响应性。
谷歌带我来这里是为了一个不同的问题,所以我将回答我正在寻找的东西,希望它能帮助别人。
在第一个例子中,async关键字丢失,导致编译器错误
protected override Task<bool> ShouldMakeADecision()
{
return true;
}
这将失败,因为您需要按照如下所示编写async关键字。你可以看到我把它放在了protected之后,override之前。
protected async override Task<bool> ShouldMakeADecision()
{
return true;
}