use*_*955 4 .net c# http async-await
我想在我的程序中实现的是以下callstack/workflow:
我的想法是,这dispatch()
将是异步的,而其他两种方法仍然是非同步的.但是,出于某种原因,除非我做了2 + 3,否则它对我不起作用.异步.也许我还有一些误解.
根据我的理解,我可以a)authorize()
在调用异步方法时使用-keyword(这将挂起方法并在异步方法完成后继续),或者b)省略httpPost()
-keyword而是调用异步方法的Task.Result返回值,将阻塞直到结果可用.
让我告诉你工作的例子:
private int dispatch(string options)
{
int res = authorize(options).Result;
return res;
}
static async private Task<int> authorize(string options)
{
string values = getValuesFromOptions(options);
KeyValuePair<int, string> response = await httpPost(url, values);
return 0;
}
public static async Task<KeyValuePair<int, string>> httpPost(string url, List<KeyValuePair<string, string>> parameters)
{
var httpClient = new HttpClient(new HttpClientHandler());
HttpResponseMessage response = await httpClient.PostAsync(url, new FormUrlEncodedContent(parameters));
int code = (int)response.StatusCode;
response.EnsureSuccessStatusCode();
string responseString = await response.Content.ReadAsStringAsync();
return new KeyValuePair<int, string>(code, responseString);
}
Run Code Online (Sandbox Code Playgroud)
让我告诉你非工作的例子:
private int dispatch(string options)
{
int res = authorize(options).Result;
return res;
}
static private int authorize(string options)
{
string values = getValuesFromOptions(options);
Task<KeyValuePair<int, string>> response = httpPost(url, values);
doSomethingWith(response.Result); // execution will hang here forever
return 0;
}
public static async Task<KeyValuePair<int, string>> httpPost(string url, List<KeyValuePair<string, string>> parameters)
{
var httpClient = new HttpClient(new HttpClientHandler());
HttpResponseMessage response = await httpClient.PostAsync(url, new FormUrlEncodedContent(parameters));
int code = (int)response.StatusCode;
response.EnsureSuccessStatusCode();
string responseString = await response.Content.ReadAsStringAsync();
return new KeyValuePair<int, string>(code, responseString);
}
Run Code Online (Sandbox Code Playgroud)
我也试图让所有3种方法的非异步,并更换httpPost()
为s await
与await
S,但随后将在该行永远挂Task.Result
有人可以启发我并解释我的错误是什么吗?
Ser*_*rvy 12
您有一个SynchronizationContext
,并且当您await
继续使用该上下文时,将捕获该上下文.
您正在启动异步任务,将调度安排在稍后的主环境中运行.
然后,在异步操作完成之前,您的主上下文中的代码会对异步操作执行阻塞等待.无法安排继续运行,因为上下文正忙于等待继续.经典的僵局.
正如您在第一个示例中所做的那样,这就是"一直异步"的重要原因.
在第二个例子中,有一些黑客可以解决僵局,但它仍然不是你应该做的事情.异步的整个过程就是避免阻塞你的线程.如果你只是对任务进行阻塞等待,那么你就是在打败异步的目的.除非您没有选择,否则要使所有内容异步,或者不要异步.
归档时间: |
|
查看次数: |
1295 次 |
最近记录: |