一次又一次,我看到它说使用async- await不会创建任何额外的线程.这没有任何意义,因为计算机一次看起来只做一件事以上的唯一方法就是
因此,如果async- await这些都没有,那么它如何使应用程序响应?如果只有一个线程,则调用任何方法意味着在执行任何其他操作之前等待方法完成,并且该方法中的方法必须在继续之前等待结果,依此类推.
据我所知,yield关键字,如果从迭代器块内部使用,它会将控制流返回给调用代码,当再次调用迭代器时,它会从中断处继续.
此外,await不仅等待被调用者,而且还将控制权返回给调用者,仅在调用者调用awaits方法时从中断处获取.
换句话说 - 没有线程,async和await的"并发"是一种由巧妙的控制流引起的错觉,其细节被语法隐藏.
现在,我是一名前汇编程序员,我对指令指针,堆栈等非常熟悉,并且我得到了正常的控制流(子程序,递归,循环,分支)的工作方式.但是这些新的结构 - 我没有得到它们.
当await到达,如何运行时知道什么是一段代码接下来应该执行?它是如何知道什么时候可以从它停止的地方恢复的,它如何记住在哪里?当前的调用堆栈会发生什么,它会以某种方式保存吗?如果调用方法在其之前进行其他方法调用,那么该await怎么办?为什么堆栈不会被覆盖呢?在异常和堆栈展开的情况下,运行时如何在所有这些中运行?
何时yield到达,运行时如何跟踪应该拾取事物的点?迭代器状态如何保存?
有一些文章指出异步数据库调用在.NET中是个坏主意.
在C#Async CTP上,有一个System.Data.SqlClient.SqlCommand名为的扩展名ExecuteReaderAsync.我在现有代码上有如下操作:
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["hubConnectionString"].ConnectionString;
using (var conn = new SqlConnection(connectionString)) {
using (var cmd = new SqlCommand()) {
cmd.Connection = conn;
cmd.CommandText = "sp$DetailsTagsGetAllFromApprovedPropsWithCount";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
conn.Open();
var reader = cmd.ExecuteReader();
while (reader.Read()) {
//do the reading
}
conn.Close();
}
}
Run Code Online (Sandbox Code Playgroud)
在我的代码上有几个这样的操作.所以,我正在考虑将这些转换为异步.
但另一方面,我并没有看到这种方法有多大的吸引力(也许我没有看到正确的方向,谁知道!).
那么,这里使用这种新的异步编程模型有什么缺点吗?
编辑:
假设我重构代码如下:
public async Task<IEnumerable<Foo>> GetDataAsync() {
List<Foo> foos = new List<Foo>();
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["hubConnectionString"].ConnectionString;
using (var conn = new SqlConnection(connectionString)) {
using (var cmd …Run Code Online (Sandbox Code Playgroud) 我正在做一些研究,以更好地理解C#的异步/等待。
我发现一个网站,其中包含以下代码,以显示同步处理与异步/等待相比要慢多少:
public IActionResult Index()
{
Stopwatch watch = new Stopwatch();
watch.Start();
ContentManagement service = new ContentManagement();
var content = service.GetContent();
var count = service.GetCount();
var name = service.GetName();
watch.Stop();
ViewBag.WatchMilliseconds = watch.ElapsedMilliseconds;
return View();
}
[HttpGet]
public async Task<ActionResult> IndexAsync()
{
Stopwatch watch = new Stopwatch();
watch.Start();
ContentManagement service = new ContentManagement();
var contentTask = service.GetContentAsync();
var countTask = service.GetCountAsync();
var nameTask = service.GetNameAsync();
var content = await contentTask;
var count = await countTask;
var name = await nameTask; …Run Code Online (Sandbox Code Playgroud) 在这里,我有两个功能static int Main()和static async Task<int> Main()。
谁能告诉我他们有什么区别?
static int Main()
{
return DoAsyncWork().GetAwaiter().GetResult();
}
static async Task<int> Main()
{
return await DoAsyncWork();
}
Run Code Online (Sandbox Code Playgroud)
并且是await。
具有以下签名的Web API方法实际返回了什么?
[HttpPost]
public async Task<IHttpActionResult> Post([FromBody] ReviewViewModel review)
{
using (var context = new BooksContext())
{
var book = await context.Books.FirstOrDefaultAsync(b => b.Id == review.BookId);
if (book == null)
{
return NotFound();
}
var newReview = context.Reviews.Add(new Review
{
BookId = book.Id,
Description = review.Description,
Rating = review.Rating
});
await context.SaveChangesAsync();
return Ok(new ReviewViewModel(newReview));
}
}
Run Code Online (Sandbox Code Playgroud)
方法取自:http://www.developerhandbook.com/c-sharp/create-restful-api-authentication-using-web-api-jwt/
我在考虑它是:
1)在.IsCompleted为真之前,框架不会向调用客户端返回响应,或者2)框架确实返回到客户端,但客户端必须优雅地处理这种情况,或者3)完全没有其他东西.