在Task中返回true或false的异步方法

本文关键字:false 异步方法 true Task 返回 | 更新日期: 2023-09-27 18:03:27

我知道async方法只能返回voidTask。我已经阅读了async方法内部异常处理的类似方法。我是async编程的新手,所以我正在寻找一个简单的解决方案。

我的async方法运行Sql查询。如果查询正常,它应该用布尔值truefalse通知调用者。我的方法目前是一个void,所以我没有办法知道。

private async void RefreshContacts()
{
    Task refresh = Task.Run(() =>
    {
        try
        {
            // run the query
        }
        catch { }
    }
    );
    await refresh;           
}

我只是想将async更改为Task,以便在我的catch语句中该方法将返回false,否则将返回true

在Task中返回true或false的异步方法

听起来你只需要返回一个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, intstring类型的(标量)值。

我把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;
        }
    });
}

注意没有asyncawait关键字。我们只使用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;
        }