Hal*_*nac 8 c# asynchronous azure azure-table-storage async-await
使用Azure存储客户端库2.1,我正在进行表存储异步查询.我创建了这段代码:
public async Task<List<TAzureTableEntity>> GetByPartitionKey(string partitionKey)
{
var theQuery = _table.CreateQuery<TAzureTableEntity>()
.Where(tEnt => tEnt.PartitionKey == partitionKey);
TableQuerySegment<TAzureTableEntity> querySegment = null;
var returnList = new List<TAzureTableEntity>();
while(querySegment == null || querySegment.ContinuationToken != null)
{
querySegment = await theQuery.AsTableQuery()
.ExecuteSegmentedAsync(querySegment != null ?
querySegment.ContinuationToken : null);
returnList.AddRange(querySegment);
}
return returnList;
}
Run Code Online (Sandbox Code Playgroud)
假设有大量数据返回,因此会有很多往返表存储的往返.我遇到的问题是我们正在等待一组数据,将其添加到内存列表中,等待更多数据,将其添加到同一列表中,等待更多数据,将其添加到列表中......等等等等.为什么不围绕常规TableQuery包装Task.Factory.StartNew()?像这样:
public async Task<List<TAzureTableEntity>> GetByPartitionKey(string partitionKey)
{
var returnList = await Task.Factory.StartNew(() =>
table.CreateQuery<TAzureTableEntity>()
.Where(ent => ent.PartitionKey == partitionKey)
.ToList());
return returnList;
}
Run Code Online (Sandbox Code Playgroud)
这样做似乎我们不会来回反复播放SynchronizationContext.或者它真的重要吗?
编辑以改写问题
上面提到的两种情况有什么区别?
两者之间的区别在于您的第二个版本将ThreadPool
在执行查询的整个过程中阻塞一个线程.这在GUI应用程序中是可以接受的(你想要的只是在UI线程以外的地方执行代码),但它会否定async
服务器应用程序中的任何可伸缩性优势.
此外,如果您不希望第一个版本返回到每个往返的UI上下文(这是一个合理的要求),那么ConfigureAwait(false)
无论何时使用都使用await
:
querySegment = await theQuery.AsTableQuery()
.ExecuteSegmentedAsync(…)
.ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
这样,第一个之后的所有迭代将(很可能)在ThreadPool
线程上而不是在UI上下文上执行.
顺便说一句,在你的第二个版本中,你根本不需要await
,你可以直接返回Task
:
public Task<List<TAzureTableEntity>> GetByPartitionKey(string partitionKey)
{
return Task.Run(() => table.CreateQuery<TAzureTableEntity>()
.Where(ent => ent.PartitionKey == partitionKey)
.ToList());
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
10399 次 |
最近记录: |