繁体   English   中英

我实际上如何在C#中编写/结束异步方法?

[英]How do I actually write/end an async method in c#?

我得到我需要等待async标记方法中的内容以使其异步,但是我不知道如何实际结束它造成的漏洞。

static async void Example()
{
    int t = await getIntAsync();
    WriteLine($"computer: {t}");
}

由于getIntAsync被标记为异步,因此我必须在该方法中等待,否则会收到警告。 但是,哦,我在getIntAsync中等待的方法中没有,我必须将其标记为aasync,然后除非那里有等待,否则我会得到警告。 依此类推,直至无穷大。 我如何使其停止?

我有几个人告诉我放

await Task.Delay(1000);  

在我的代码中,但是我知道答案不会像在我的所有生产代码中都花一秒钟的延迟一样难闻。

其他一些人说可以结束任务的任务方法,例如

static Task task()
{
  //code
}

但是除非我标记为async ,否则它将引发同样的警告,使我陷入混乱。 我知道

static Task task()
{
  //code
  return Task.FromResult(0);
}

从技术上讲,它可以正常工作,但同样,似乎又有太多的代码味道,无法全面投入生产。

我就是不明白...

编辑:因为有人要求。 我知道这是一种非常琐碎的方法,但也只是我用于练习的一种方法。

    static async Task<int> getIntAsync()
    {

        Console.Write("Enter the number: ");
        int n = int.Parse(Console.ReadLine());
        return n;

    }

令人困惑的是,您实际上并没有做异步的事情。 Console.ReadLine()是一种同步方法。 仅仅await某个地方键入asyncawait并不能神奇地使它异步。

由于此代码仅用于测试和学习,因此使其异步的一种方法是使用Task.Run()将其放在另一个线程上Task.Run()在很多情况下,我不会在生产代码中建议这样做):

static Task<int> getIntAsync()
{
    Console.Write("Enter the number: ");
    return Task.Run(() => int.Parse(Console.ReadLine());
}

这里不需要async关键字,因为您不需要等待。 您只需返回一个Task<int> ,当用户输入一个值并对该值进行了解析时,该完成即可。

然后您的Example()方法将像这样工作:

static async void Example()
{
    int t = await getIntAsync();
    WriteLine($"computer: {t}");
}

按下await ,控制流将返回给调用方,并且此方法的其余部分(对t的赋值和对Console.WriteLine()的调用)被安排为在Task<int>返回时执行的延续由getIntAsync()完成。

需要以下内容(async关键字是必需的,await也是,这是最佳实践):

  1. 异步关键字
  2. Await关键字
  3. 您希望在异步进程运行时独立工作的某些进程。
  4. 通常,您的返回值来自您的等待任务(应填入端孔)。

这是使用StreamReader的示例,

async Task<string> GetStringFromReaderAsync()
{
  Streamreader sr = new StreamReader("filename.txt");

     Task<string> getStringTask = sr.ReadLineAsync("filepath");

    //Allow user to continue with some other work.
     DoFileLookup();

  string result = await sr.getStringTask();

  return result.ToString();

}

此处的更多信息: https : //msdn.microsoft.com/zh-cn/library/system.io.streamreader.readlineasync(v=vs.110).aspx

有关异步和等待的更多信息: https : //msdn.microsoft.com/zh-cn/library/mt674882.aspx

 static async Task<int> getIntAsync() { Console.Write("Enter the number: "); int n = int.Parse(Console.ReadLine()); return n; } 

这将同步运行,因为没有等待语句,也没有等待调用的异步方法

一般的想法是这样

   public async Task<int> ExecuteAsync() //Method return type is Task<int>
   {
      // Error: return type is not int. Return type is Task<int>
      return db.SaveChangesAsync(); 

      // OK: returns a task handle that you can await on in you code that called ExecuteAsync()
      // you thread continues processing in your calling function until you try to read the value from this return statement.
      return await db.SaveChangesAsync(); 

      // Ok. Your Thread leaves here and returns when result available.
      // no further Processing done in calling function
      return db.SaveChangesAsync().Result; 

      // Ok. This is not required in this case, 
      // but if you have an async method that has multiple return points, 
      // and one of them does not depend on an async method, you can wrap
      // the output e.g. return await Task.FromResult(0); 
      return await Task.FromResult(db.SaveChangesAsync().Result); 

      return 0; //also ok.
   }

在下面添加其他答案。

static async Task<int> GetIntAsync()
{
    Console.Write("Enter the number: ");
    return await Task.Run(() => int.Parse("1"));
}

这种方法使得可以同步运行的东西被包装在任务中。 但是,您永远不要这样做(除非您当然知道自己在做什么),因为这会产生另一个线程。 我曾经用过的一个用例是在Web服务器上进行卸载,但是通常这是一个坏主意。 因此,尽管您可能最初打算最大程度地利用单个线程,但是现在您最终只能使用两个线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM