我试图理解为什么ASP.Net应用程序中的异步void方法可能导致以下异常,而async Task似乎不会:
System.InvalidOperationException: An asynchronous module or handler
completed while an asynchronous operation was still pending
Run Code Online (Sandbox Code Playgroud)
我对.NET中的异步世界相对较新,但我觉得我试图通过一些现有资源来运行这个,包括以下所有内容:
从这些资源中,我了解最佳做法是通常返回Task并避免异步void.我也理解async void会在调用方法时增加未完成操作的数量,并在完成时减少它.这听起来至少是我问题答案的一部分.但是,我遗漏的是当我返回Task时会发生什么,以及为什么这样做会让事情变得"有效".
这是一个人为的例子来进一步说明我的问题:
public class HomeController : AsyncController
{
// This method will work fine
public async Task<ActionResult> ThisPageWillLoad()
{
// Do not await the task since it is meant to be fire and forget
var task = this.FireAndForgetTask();
return await Task.FromResult(this.View("Index"));
}
private async Task FireAndForgetTask()
{
var task = Task.Delay(TimeSpan.FromSeconds(3));
await task;
}
// This …Run Code Online (Sandbox Code Playgroud) 我们有一个包含超过1000多个表的数据库,并且想考虑将EF4用于我们的数据访问层,但我担心将它用于这样一个大型数据模型的实际现实.我已经看到了这个问题,并在这里和这里阅读了建议的解决方案.这些可能有效,但似乎是指实体框架的第一个版本(并且比我想要的更复杂).有谁知道这些解决方案是否在EF4中有所改进?或者还有其他建议吗?谢谢.
更新:经过多次尝试使EF工作,我决定放弃这一项目.大数据模型支持不存在,虽然可能存在解决方法(例如,编辑和维护xml独立于设计者),但他们只是没有为黄金时间做好准备.对我来说最大的问题是EF不能很好地与分布在多个XML文件中的域模型一起工作,而没有大量的冗余和代码重复.我仍然愿意接受建议(我知道我没有剥掉EF洋葱的所有层),但是现在,我正在继续前进而没有EF.
更新#2:看起来挂起的代码首次支持(目前在EF4 CTP4中)可能最终成为我们想要的解决方案,因为它使设计人员和大型XML文件维护无法发挥作用.
假设您有一个包含三列的大型表,如下所示:
[id] INT NOT NULL,
[date] SMALLDATETIME NOT NULL,
[sales] FLOAT NULL
Run Code Online (Sandbox Code Playgroud)
还假设您仅限于一个物理磁盘和一个文件组(PRIMARY).您希望此表能够在100个日期(10,000个以上的记录)中保持10,000,000+ ID的销售额.
与许多数据仓库方案一样,数据通常按日期顺序增长(即,每次执行数据加载时,您将插入新日期,并可能更新一些最近的数据日期).出于分析目的,通常会查询和聚合数据,以便随机设置~10,000个ID,这些ID将通过与另一个表的连接来指定.通常,这些查询不指定日期范围,或指定非常宽的日期范围,这引出了我的问题:索引/分区此表的最佳方法是什么?
我已经考虑了一段时间了,但我遇到了相互矛盾的解决方案:
选项#1: 由于数据将按日期顺序加载,请将聚集索引(和主键)定义为[date],[id].还可以在日期创建"滑动窗口"分区功能/方案,允许新数据快速移入/移出表格.可以在id上创建非聚集索引以帮助查询.
预期结果#1: 这种设置对于数据加载来说非常快,但在分析读取方面是次优的,在最坏的情况下(不受日期限制,不满意查询的id集),100%可以读取数据页面.
选项#2: 由于一次只查询一小部分id的数据,因此将聚簇索引(和主键)定义为[id],[date].不要费心去创建分区表.
预期结果#2: 在加载数据时预计会有巨大的性能损失,因为我们无法再按照日期快速限制.对于我的分析查询,预计会有巨大的性能优势,因为它可以最大限度地减少读取的数据页数.
选项#3:聚集(和主键)如下:[id],[date]; "滑动窗口"分区功能/方案日期.
预期结果#3:不确定会发生什么.鉴于聚集索引中的第一列是[id],因此(这是我的理解)数据按ID排列,我希望我的分析查询具有良好的性能.但是,数据按日期划分,这与聚簇索引的定义相反(但仍然对齐为日期是索引的一部分).我没有找到很多与这种情况有关的文档,以及我可以从中获得的性能优势(如果有的话),这使我得到了最终的奖金问题:
如果我在一个磁盘上的一个文件组上创建一个表,在一列上有一个聚簇索引,那么在同一列上定义一个分区时,是否有任何好处(除了加载数据时的分区切换)?
我一直在使用Web API(Web Host)作为代理服务器,并且遇到了我的Web API代理如何使用"Transfer-Encoding:chunked"标头处理响应的问题.
绕过代理时,远程资源会发送以下响应标头:
Cache-Control:no-cache
Content-Encoding:gzip
Content-Type:text/html
Date:Fri, 24 May 2013 12:42:27 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/8.0
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
Run Code Online (Sandbox Code Playgroud)
在浏览基于Web API的代理时,除非我将响应头上的TransferEncodingChunked属性显式重置为false,否则我的请求会挂起:
response.Headers.TransferEncodingChunked = false;
Run Code Online (Sandbox Code Playgroud)
我承认,我不完全了解设置TransferEncodingChunked属性有什么影响,但我觉得奇怪的是,为了使代理按预期工作,我需要将此属性设置为false,以便明确传入的响应具有" Transfer-Encoding:chunked"header.我也担心明确设置此属性的副作用.任何人都可以帮助我了解发生了什么以及为什么需要设置此属性?
更新:所以我在进行代理与非代理时,进一步深入研究了响应的差异.无论我是否将TransferEncodingChunked属性显式设置为false,通过代理时的响应标头与不通过代理时的响应标头完全相同.但是,响应内容不同.以下是一些示例(我关闭了gzip编码):
// With TransferEncodingChunked = false
2d\r\n
This was sent with transfer-encoding: chunked\r\n
0\r\n
// Without explicitly setting TransferEncodingChunked
This was sent with transfer-encoding: chunked
Run Code Online (Sandbox Code Playgroud)
显然,将TransferEncodingChunked设置为false发送的内容实际上是传输编码的.这实际上是正确的响应,因为它是从代理后面的请求资源收到的.继续奇怪的是第二种情况,我没有在响应上明确设置TransferEncodingChunked(但它在从代理服务接收的响应头中).很明显,在这种情况下,尽管事实上是响应,但响应实际上并不是由IIS进行传输编码的.奇怪......这开始感觉像设计行为(在这种情况下,我想知道如何/为什么)或IIS,ASP.Net或Web API中的错误.
这是我正在运行的代码的简化版本:
代理Web API应用程序:
// WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "Proxy",
routeTemplate: "{*path}",
handler: HttpClientFactory.CreatePipeline(
innerHandler: new HttpClientHandler(), // Routes the request to an external resource
handlers: new …Run Code Online (Sandbox Code Playgroud)