Adn*_*een 5 c# asynchronous task-parallel-library async-await
在体验4.5的新异步和等待功能时,我想在进一步讨论之前清除一些混淆.我一直在阅读不同的文章和关于SO的不同问题,它帮助我了解Async和Await如何工作.我将尝试将我的理解和困惑放在这里,并且如果某些代码教育我和其他正在寻找相同事物的人,我将非常感激.我用非常简单的措辞来讨论这个问题.
因此使用Async以便编译器知道由Async标记的方法包含Await操作(长操作).最新框架包含用于异步操作的不同新内置方法.
内置的Async函数(如connection.OpenAsync,ExecuteScalarAsync等)与Await关键字一起使用.我不知道这些异步方法的内部工作,但我强烈的猜测是,他们正在使用任务.
我可以将此作为Await与任何实现Task的方法的一般规则.因此,如果我需要创建自己的执行长操作的方法,那么我将创建它作为任务,当它被调用时,我将使用Await Keyword吗?
第二个最重要的是,将方法创建为异步或将其创建为任务的经验法则是什么.例如,
public void SampleMain()
{
for (int i = 1; i <= 100; i++)
{
DataTable dt = ReadData(int id);
}
}
public DataTable ReadData(int id)
{
DataTable resultDT = new DataTable();
DataTable dt1 = new DataTable();
// Do Operation to Fill DataTable from first connection string
adapter.Fill(dt1);
DataTable dt2 = new DataTable();
// Do Operation to Fill DataTable from first connection string
adapter.Fill(dt2);
// Code for combining datatable and returning the resulting datatable
// Combine DataTables
return resultDT;
}
public string GetPrimaryConnectionString()
{
// Retrieve connection string from some file io operations
return "some primary connection string";
}
public string GetSecondaryConnectionString()
{
// Retrieve connection string from some file io operations
return "some secondaryconnection string";
}
Run Code Online (Sandbox Code Playgroud)
现在这是一个非常简单的场景,我根据我过去工作过的一些真实世界的应用程序创建了这个场景.所以我只是想知道如何使整个过程Async.
我应该将GetPrimaryConnectionString和GetSecondaryConnectionString作为任务并在ReadData中等待它们.ReadData也是一个任务吗?如何在SampleMain函数中调用ReadData?
另一种方法是在SampleMain中为ReadData创建一个Task,并运行该Task并跳过将其他方法转换为Task.这是好方法吗?它真的是异步吗?
因此使用Async以便编译器知道Async标记的方法包含Await操作
使用它async是为了使编译器具有从该方法创建状态机的指示.一种async方法可以没有await,仍然工作,但它会执行完全同步.
内置的Async函数(如connection.OpenAsync,ExecuteScalarAsync等)与Await关键字一起使用.我不知道这些异步方法的内部工作,但我强烈的猜测是,他们正在使用任务.
Task承诺将来完成工作.有几种方法可以创建Task.但是,Task并不是唯一可以代表异步操作的东西.如果您愿意,您可以自己创建一个等待它,它需要它来实现一个GetAwaiter返回类型实现的方法INotifyCompletion.
如果您想知道如何在框架中实现方法,则可以查看源代码.在这种特殊情况下,他们使用TaskCompletionSource<T>.
我应该将GetPrimaryConnectionString和GetSecondaryConnectionString作为任务并在ReadData中等待它们.ReadData也是一个任务吗?如何在SampleMain函数中调用ReadData?
检索连接字符串没有任何固有的异步.您通常(并非总是)使用async-await自然异步IO操作.在这种特殊情况下,唯一的实际异步操作是ReadData,如果你想让它异步,你可以使用SqlDataReader,它暴露了异步方法.
一个例子,取自ADO.NET团队的博客:
public static async Task<Product> GetProductAndReviewsAsync(
int productID, int reviewsToGet)
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
await connection.OpenAsync();
const string commandString = GetProductByIdCommand + ";"
+ GetProductReviewsPagedById;
using (SqlCommand command = new SqlCommand(commandString, connection))
{
command.Parameters.AddWithValue("productid", productID);
command.Parameters.AddWithValue("reviewStart", 0);
command.Parameters.AddWithValue("reviewCount", reviewsToGet);
using (SqlDataReader reader = await command.ExecuteReaderAsync())
{
if (await reader.ReadAsync())
{
Product product = GetProductFromReader(reader, productID);
if (await reader.NextResultAsync())
{
List<Review> allReviews = new List<Review>();
while (await reader.ReadAsync())
{
Review review = GetReviewFromReader(reader);
allReviews.Add(review);
}
product.Reviews = allReviews.AsReadOnly();
return product;
}
else
{
throw new InvalidOperationException(
"Query to server failed to return list of reviews");
}
}
else
{
return null;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1070 次 |
| 最近记录: |