当你有服务器端代码(即一些ApiController)并且你的函数是异步的 - 所以它们返回Task<SomeObject>- 你认为最好的做法是等待你调用的函数ConfigureAwait(false)吗?
我已经读过它更高效,因为它不必将线程上下文切换回原始线程上下文.但是,使用ASP.NET Web Api,如果您的请求是在一个线程上进行的,并且等待某些函数和调用ConfigureAwait(false),则可能会在返回ApiController函数的最终结果时将您置于不同的线程上.
我在下面输入了一个我正在谈论的例子:
public class CustomerController : ApiController
{
public async Task<Customer> Get(int id)
{
// you are on a particular thread here
var customer = await SomeAsyncFunctionThatGetsCustomer(id).ConfigureAwait(false);
// now you are on a different thread! will that cause problems?
return customer;
}
}
Run Code Online (Sandbox Code Playgroud) 我有以下四个测试,当我运行它时,最后一个测试挂起,我的问题是为什么会发生这种情况:
[Test]
public void CheckOnceResultTest()
{
Assert.IsTrue(CheckStatus().Result);
}
[Test]
public async void CheckOnceAwaitTest()
{
Assert.IsTrue(await CheckStatus());
}
[Test]
public async void CheckStatusTwiceAwaitTest()
{
Assert.IsTrue(await CheckStatus());
Assert.IsTrue(await CheckStatus());
}
[Test]
public async void CheckStatusTwiceResultTest()
{
Assert.IsTrue(CheckStatus().Result); // This hangs
Assert.IsTrue(await CheckStatus());
}
private async Task<bool> CheckStatus()
{
var restClient = new RestClient(@"https://api.test.nordnet.se/next/1");
Task<IRestResponse<DummyServiceStatus>> restResponse = restClient.ExecuteTaskAsync<DummyServiceStatus>(new RestRequest(Method.GET));
IRestResponse<DummyServiceStatus> response = await restResponse;
return response.Data.SystemRunning;
}
Run Code Online (Sandbox Code Playgroud)
我将此扩展方法用于restsharp RestClient:
public static class RestClientExt
{
public static Task<IRestResponse<T>> ExecuteTaskAsync<T>(this RestClient client, IRestRequest …Run Code Online (Sandbox Code Playgroud) 我们有这个方法:
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();
string urlContents = await getStringTask;
//The thing is that this returns an int to a method that has a return type of Task<int>
return urlContents.Length;
}
Run Code Online (Sandbox Code Playgroud)
之间是否隐式转换发生Task<int>和int?如果没有,那么发生了什么?它是如何实现的?
我正在C#Win8 CP上基于xaml的metro应用程序内部进行调用; 此调用只是命中一个Web服务并返回JSON数据.
HttpMessageHandler handler = new HttpClientHandler();
HttpClient httpClient = new HttpClient(handler);
httpClient.BaseAddress = new Uri("http://192.168.1.101/api/");
var result = await httpClient.GetStreamAsync("weeklyplan");
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(WeeklyPlanData[]));
return (WeeklyPlanData[])ser.ReadObject(result);
Run Code Online (Sandbox Code Playgroud)
它挂起,await但http呼叫几乎立即返回(通过提琴手确认); 就好像await被忽略了它只是挂在那里.
在您询问之前 - 是 - 打开了专用网络功能.
任何想法为什么会挂起?
public async Task<string> GetName(int id)
{
Task<string> nameTask =
Task.Factory.StartNew(() => { return string.Format("Name matching id {0} = Developer", id); });
return nameTask.Result;
}
Run Code Online (Sandbox Code Playgroud)
在上面的方法return语句我使用Task.Result属性.
public async Task<string> GetName(int id)
{
Task<string> nameTask =
Task.Factory.StartNew(() => { return string.Format("Name matching id {0} = Developer", id); });
return await nameTask;
}
Run Code Online (Sandbox Code Playgroud)
我在这里使用等待任务.如果我认为await将释放调用线程但是Task.Result将阻止它,我会不会错,它会是正确的吗?
错误CS1061"任务>"不包含"FirstOrDefault"的定义,并且没有可以找到接受"任务>"类型的第一个参数的扩展方法"FirstOrDefault"(您是否缺少using指令或程序集引用?),
用facebook控制器创建一个web应用程序,包括使用system.linq,但仍然得到错误FirstOrDefault().我不知道问题是什么,我重新安装了视觉工作室,因为他同样的事情适用于我的朋友笔记本电脑.我耍弄了一下,看看这个方法是否存在于库中并且它存在但是仍然没有超过这个图像
public async Task<ActionResult> Posts()
{
var currentClaims = UserManager.GetClaimsAsync(HttpContext.Identity.GetUserId());
// Error occurs here at FirstOrDefault
var accesstoken = currentClaims.FirstOrDefault(x = > x.Type == "urn:tokens:facebook");
if (accesstoken == null)
...
}
Run Code Online (Sandbox Code Playgroud) 我在 C# 中有这个 xUnit 方法来测试 web api
[Fact]
public async Task GetWeatherForecast()
{
var apiClient = new HttpClient();
var apiResponse = await apiClient.GetAsync($"http://xxx/weatherforecast").Result;
Assert.True(apiResponse.IsSuccessStatusCode);
}
Run Code Online (Sandbox Code Playgroud)
但是遇到了这个错误HttpResponseMessage' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter'。如果我删除async Task和await,它可以成功运行。
c# ×7
async-await ×6
asynchronous ×2
.net ×1
.net-4.5 ×1
c#-5.0 ×1
deadlock ×1
nunit ×1
task ×1