编辑:在测试用例5中,任务似乎处于waitingforactivation
状态。
我在.NET 4.5中使用System.net.http.HttpClient时遇到了一些奇怪的行为--其中“等待”调用的结果(例如)HttpClient.getAsync(...)
将永远不会返回。
只有在使用新的Async/Await语言功能和任务API的特定情况下才会出现这种情况--代码似乎总是在只使用延续时工作。
/api/test1
/api/test2
/api/test3
/api/test4
/api/test5 <--- never completes
/api/test6
public class BaseApiController : ApiController
{
/// <summary>
/// Retrieves data using continuations
/// </summary>
protected Task<string> Continuations_GetSomeDataAsync()
{
var httpClient = new HttpClient();
var t = httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead);
return t.ContinueWith(t1 => t1.Result.Content.Headers.ToString());
}
/// <summary>
/// Retrieves data using async/await
/// </summary>
protected async Task<string> AsyncAwait_GetSomeDataAsync()
{
var httpClient = new HttpClient();
var result = await httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead);
return result.Content.Headers.ToString();
}
}
public class Test1Controller : BaseApiController
{
/// <summary>
/// Handles task using Async/Await
/// </summary>
public async Task<string> Get()
{
var data = await Continuations_GetSomeDataAsync();
return data;
}
}
public class Test2Controller : BaseApiController
{
/// <summary>
/// Handles task by blocking the thread until the task completes
/// </summary>
public string Get()
{
var task = Continuations_GetSomeDataAsync();
var data = task.GetAwaiter().GetResult();
return data;
}
}
public class Test3Controller : BaseApiController
{
/// <summary>
/// Passes the task back to the controller host
/// </summary>
public Task<string> Get()
{
return Continuations_GetSomeDataAsync();
}
}
public class Test4Controller : BaseApiController
{
/// <summary>
/// Handles task using Async/Await
/// </summary>
public async Task<string> Get()
{
var data = await AsyncAwait_GetSomeDataAsync();
return data;
}
}
public class Test5Controller : BaseApiController
{
/// <summary>
/// Handles task by blocking the thread until the task completes
/// </summary>
public string Get()
{
var task = AsyncAwait_GetSomeDataAsync();
var data = task.GetAwaiter().GetResult();
return data;
}
}
public class Test6Controller : BaseApiController
{
/// <summary>
/// Passes the task back to the controller host
/// </summary>
public Task<string> Get()
{
return AsyncAwait_GetSomeDataAsync();
}
}
您正在滥用API。
情况如下:在ASP.NET中,一次只能有一个线程处理一个请求。如果需要,您可以执行一些并行处理(从线程池中借用额外的线程),但只有一个线程具有请求上下文(其他线程不具有请求上下文)。
这由ASP.NETSynchronizationContext
管理。
test1
、test2
和test3
):continuations_getSomeDataAsync
将继续调度到ASP.NET请求上下文之外的线程池中。这使得continuations_getSomeDataAsync
返回的任务
可以完成,而不必重新输入请求上下文。test4
和test6
):由于等待任务
,因此ASP.NET请求线程不会被阻塞。这允许AsyncaWait_GetSomeDataAsync
在准备继续时使用ASP.NET请求上下文。以下是最佳实践:
异步
方法中,尽可能使用configureawait(false)
。在您的示例中,这将AsyncaWait_getsomedataAsync
更改为var result=await httpclient.getAsync(“http://stackoverflow.com”,httpcompletionoption.responseHeadersread).configureaWait(false);
任务
;它是异步
。换句话说,使用await
而不是getresult
(task.result
和task.wait
也应该替换为await
)。这样,您可以获得两个好处:continuation(AsyncaWait_GetSomeDataAsync
方法的其余部分)在基本线程池线程上运行,该线程不必进入ASP.NET请求上下文;控制器本身是异步
(它不会阻塞请求线程)。
更多信息:
异步
/等待
介绍帖子,其中包括任务
等待者如何使用synchronizationcontext
的简要说明。SynchronizationContext
将请求上下文限制为一次只能有一个线程。所以我一直很高兴地使用async/await,因为Firebase云函数支持节点8。不过我有一件事要做。当使用可调用函数时,会告诉您必须在函数中返回promise,否则它将无法正常工作。当使用原始promise时,我很清楚如何使用它: 但是现在,随着异步等待,我不确定如何返回这个“promise链”: 有人知道吗?
问题内容: 为了熟悉,我在Chrome中尝试了以下代码: 但不保存结果(字符串);而是持有一个需要再次等待的。这段代码确实给了我响应字符串: 如何使用await从函数返回实际的响应字符串? 问题答案: 要么 要么 这只是编写相同逻辑的另一种方法。
> < li >我在组织的租户azure环境中部署了一个ASP.NET(4.5)网站。 < li >它具有从网络位置(我们称之为nas驱动器)上传/下载/删除文件(任何类型)的功能,例如\nas8782\xyz\abc\ < li> 上传/下载/删除工作正常(参见下面的代码)。我们用的是CloudSdk。由我们的Azure团队创建的Azure库。 nasClient.UploadAsync nas
Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。 Async function 让我们以 async 这个关键字开始。它可以被放置在一个函数前面,如下所示: async function f() { return 1; } 在函数前面的 “async” 这个单词表达了一个简单的事情:即这个函数总是返回一个 promise。其他值将自动被
在第一章节,我们简要介绍了async/.await,并用它来构建一个简单的服务器。本章将更为详细讨论async/.await的它如何工作以及如何async代码与传统的 Rust 程序不同。 async/.await是 Rust 语法的特殊部分,它使得可以 yield 对当前线程的控制而不是阻塞,从而允许在等待操作完成时,其他代码可以运行。 async有两种主要的使用方式:async fn和asyn
用asyncio提供的@asyncio.coroutine可以把一个generator标记为coroutine类型,然后在coroutine内部用yield from调用另一个coroutine实现异步操作。 为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法async和await,可以让coroutine的代码更简洁易读。 请注意,async和await是针对coroutin