把我的脑袋缠绕在异步等待着

时间:2017-04-28 20:02:10

标签: c# .net asynchronous

原谅明显的新手问题。有一些关于异步的东西,等待着我没有抓住。

为了使方法成为异步,它必须等待从也是异步的任务/方法返回。正确?但在某些时候,不可能有一个不同步或者不会等待任何事情的任务吗?

我一直在阅读这两个教程:

https://msdn.microsoft.com/en-us/magazine/hh456401.aspx

https://msdn.microsoft.com/en-us/library/mt674882.aspx

我一直在寻找其他很多线索。但仍有一些我不明白的事情。我试着给出一个简单的例子。我想说我想为数据库中的列写一个值:

 public async Task<SimpleObject> ExecuteAsync(int rowID, string value)
 {
    return await WriteToDB(int rowID, string value);
 }

到目前为止一切顺利。但是,在这里我迷路了:

 public async Task<SimpleObject> WriteToDB(int rowID, string value)
 {
      var dataRow = context. /// use linq to get a row with rowID
      dataRow.SomeColumn = value
      context.SaveChanges();
      var simpleObject = new SimpleObject();
      simpleObject.success = true;
      return simpleObject;
 }

 public class SimpleObject
 {
    public bool success {get;set;}
 }

我非常礼貌地告诉我,我的方法WriteToDB()缺少await并且会同步运行。我仍然可以编译,并且不会出现运行时错误。但是,我无法弄明如何在await内使用WriteToDB()

3 个答案:

答案 0 :(得分:3)

您需要使用.SaveChangesAsync方法。

 public async Task<SimpleObject> WriteToDB(int rowID, string value)
 {
      var dataRow = context. 
      dataRow.SomeColumn = value
      await context.SaveChangesAsync(); //change this line
      var simpleObject = new SimpleObject();
      simpleObject.success = true;
      return simpleObject;
 }

答案 1 :(得分:2)

EntityFramework支持async query and save operations,例如SaveChangesAsync和ToListAsync,这些异步方法遵循"Task-based Asynchronous Pattern"并返回您可以等待的TaskTask<T>

您可以重写代码以执行查询并以异步方式保存,如下所示:

public async Task<SimpleObject> WriteToDB(int rowID, string value)
{
    var dataRow = await context.table.SingleAsync(item =>item.Id = /*some value*/);
    dataRow.SomeColumn = value
    await context.SaveChangesAsync();
    var simpleObject = new SimpleObject();
    simpleObject.success = true;
    return simpleObject;
}

答案 2 :(得分:1)

  

我试着给出一个简单的例子。

正如其他人所说,简单示例的简单答案是&#34;使用SaveChangesAsync代替SaveChanges&#34;。

要回答更广泛的问题&#34;如何开始使用async&#34;,最好的方法是:

  1. 识别代码库中的自然异步操作。这些通常是I / O操作。在此示例中,保存对数据库的更改。
  2. 将这些API更改为使用异步API,并使用await。在此示例中,将SaveChanges更改为await SaveChangesAsync
  3. 编译器会通知您更改包含方法以使用async,它还会为您提供正确的返回类型。在此示例中,编译器将指示您将SimpleObject WriteToDB(..)更改为async Task<SimpleObject> WriteToDBAsync(..)
  4. 重复步骤(2)和(3),直到您的应用程序编译完成。在此示例中,步骤(2)会将调用return WriteToDB(int rowID, string value);更改为return await WriteToDBAsync(int rowID, string value);,而步骤(3)会将SimpleObject Execute(..)更改为async Task<SimpleObject> ExecuteAsync(..)

    以这种方式应用async / await要容易得多,从最低级别开始并从那里开始增长。

      

    但是在某些时候,不会有一项任务不是异步或者不会等待任何事情吗?

    是。最低级别的方法通常由TaskFactory.FromAsyncTaskCompletionSource<T>实施。