C# 异步任务永远不会在简单的API客户机中结束。僵局
我是C#新手,我很可能误解了wait、async和Tasks的正确用法:) 我想开发一个类(C# 异步任务永远不会在简单的API客户机中结束。僵局,c#,.net,async-await,deadlock,asynchttpclient,C#,.net,Async Await,Deadlock,Asynchttpclient,我是C#新手,我很可能误解了wait、async和Tasks的正确用法:) 我想开发一个类(OWConnector),作为我的应用程序的API客户端,为此,我开发了一个通用的PostRequest方法来执行POST请求 不幸的是,当我使用auth方法(使用泛型方法PostRequest)时,应用程序似乎陷入了死锁 你能帮我弄清楚问题出在哪里吗?我在代码中标记了调试器永远等待的位置 // the debugger get stacked here :( 形式方法 private void bt
OWConnector
),作为我的应用程序的API客户端,为此,我开发了一个通用的PostRequest
方法来执行POST请求
不幸的是,当我使用auth方法(使用泛型方法PostRequest
)时,应用程序似乎陷入了死锁
你能帮我弄清楚问题出在哪里吗?我在代码中标记了调试器永远等待的位置
// the debugger get stacked here :(
形式方法
private void btnAnalyze_Click(object sender, EventArgs e)
{
OWConnector api = new OWConnector(@"http://mywebsite.com/");
Boolean didAuth = api.auth("myuser", "mypass");
if (didAuth)
{
MessageBox.Show(@"success :)");
}
else
{
MessageBox.Show(@"failed :(");
}
}
OWConnector类
class OWConnector
{
private CookieContainer cookieJar;
private HttpClientHandler handler;
private HttpClient client;
private Uri baseUri;
public OWConnector(string baseUrl)
{
baseUri = new Uri(baseUrl);
cookieJar = new CookieContainer();
handler = new HttpClientHandler();
handler.CookieContainer = cookieJar;
handler.UseCookies = true;
handler.AllowAutoRedirect = false;
client = new HttpClient(handler);
client.BaseAddress = baseUri;
}
public async Task<RequestResponse> PostRequest(string url, HttpContent data = null)
{
RequestResponse response = new RequestResponse();
try
{
// the debugger get stacked here :(
response.httpResponse = await client.PostAsync(url, data);
}
catch (System.AggregateException e)
{
response.error = true;
foreach (Exception ie in e.InnerExceptions)
{
response.errorMessage += ie.GetType().ToString() + ": " + ie.Message + "\n";
}
}
return response;
}
public Boolean auth(string username, string password)
{
var content = new FormUrlEncodedContent(new[]{
new KeyValuePair<string, string>(@"form_name", @"sign-in"),
new KeyValuePair<string, string>(@"identity", username),
new KeyValuePair<string, string>(@"password", password),
new KeyValuePair<string, string>(@"remember", @"on"),
new KeyValuePair<string, string>(@"submit", @"Sign In"),
});
RequestResponse r = PostRequest(@"/", content).Result;
Boolean cookieFound = false;
foreach (Cookie c in cookieJar.GetCookies(baseUri))
{
if (c.Name == @"ow_login")
{
cookieFound = true;
}
}
return cookieFound;
}
}
class RequestResponse
{
public Boolean error;
public string errorMessage;
public HttpResponseMessage httpResponse;
public RequestResponse()
{
error = false;
errorMessage = @"";
}
}
class连接器
{
私人厨师容器厨师;
私有HttpClientHandler处理器;
私有HttpClient;
私有Uri baseUri;
公共OWConnector(字符串baseUrl)
{
baseUri=新的Uri(baseUrl);
cookieJar=新CookieContainer();
handler=新的HttpClientHandler();
handler.CookieContainer=cookieJar;
handler.UseCookies=true;
handler.AllowAutoRedirect=false;
客户机=新的HttpClient(处理程序);
client.BaseAddress=baseUri;
}
公共异步任务PostRequest(字符串url,HttpContent数据=null)
{
RequestResponse=新的RequestResponse();
尝试
{
//调试器堆积在这里:(
response.httpResponse=wait client.PostAsync(url,数据);
}
捕获(System.AggregateException e)
{
response.error=true;
foreach(e.InnerExceptions中的异常)
{
response.errorMessage+=ie.GetType().ToString()+“:“+ie.Message+”\n”;
}
}
返回响应;
}
公共布尔身份验证(字符串用户名、字符串密码)
{
var content=newformurlencodedcontent(new[]{
新的KeyValuePair(@“表单名称”,“登录”),
新的KeyValuePair(@“标识”,用户名),
新的KeyValuePair(@“password”,password),
新的KeyValuePair(@“记住”,@“打开”),
新的KeyValuePair(@“提交”、“登录”),
});
RequestResponse r=PostRequest(@/),content.Result;
布尔cookieFound=false;
foreach(cookieJar.GetCookies(baseUri)中的cookiec)
{
如果(c.Name=@“ow_登录”)
{
cookieFound=真;
}
}
返回找到的Cookie;
}
}
类请求响应
{
公共布尔错误;
公共字符串错误消息;
公共httpResponse消息httpResponse;
公共请求响应()
{
错误=错误;
errorMessage=@;
}
}
您正在使用任务阻塞异步操作。结果
。您正在执行
从事件处理程序(应该是async void
)一直向下(使用async Task
),您的流应该是async
)
您正在使用
Task.Result
阻止异步操作。您正在执行
从事件处理程序(应该是async void
)一直向下(使用async Task
),您的流应该是async
)
您正在使用
Task.Result
阻止异步操作。您正在执行
从事件处理程序(应该是async void
)一直向下(使用async Task
),您的流应该是async
)
您正在使用
Task.Result
阻止异步操作。您正在执行
从事件处理程序(应该是async void
)一直向下(使用async Task
),您的流应该是async
)
您需要等待
PostRequest
完成才能访问结果
您需要等待PostRequest
完成才能访问结果
您需要等待PostRequest
完成才能访问结果
您需要等待PostRequest
在您访问结果之前要完成,谢谢,这就像一个咒语!因此,根据经验法则,我的调用堆栈中的所有方法调用都必须从事件的生成开始是异步的,对吗?谢谢,这就像一个咒语!因此,根据经验法则,我的调用堆栈中的所有方法调用都必须从m是事件的生成,对吗?谢谢,这就像一个咒语!因此,作为一个经验法则,我的调用堆栈中的所有方法调用从事件生成开始必须是异步的,对吗?谢谢,这就像一个咒语!因此作为一个经验法则,我的调用堆栈中的所有方法调用必须从e的生成开始是异步的通风孔,对吗?
private async void btnAnalyze_Click(object sender, EventArgs e)
{
OWConnector api = new OWConnector(@"http://mywebsite.com/");
Boolean didAuth = await api.authAsync("myuser", "mypass");
if (didAuth)
{
MessageBox.Show(@"success :)");
}
else
{
MessageBox.Show(@"failed :(");
}
}
class OWConnector
{
// same as in OP...
public async Task<bool> authAsync(string username, string password)
{
var content = new FormUrlEncodedContent(new[]{
new KeyValuePair<string, string>(@"form_name", @"sign-in"),
new KeyValuePair<string, string>(@"identity", username),
new KeyValuePair<string, string>(@"password", password),
new KeyValuePair<string, string>(@"remember", @"on"),
new KeyValuePair<string, string>(@"submit", @"Sign In"),
});
RequestResponse r = await PostRequest(@"/", content);
Boolean cookieFound = false;
foreach (Cookie c in cookieJar.GetCookies(baseUri))
{
if (c.Name == @"ow_login")
{
cookieFound = true;
}
}
return cookieFound;
}
}
public async Task<bool> authAsync(string username, string password)
{
var content = new FormUrlEncodedContent(new[]{
new KeyValuePair<string, string>(@"form_name", @"sign-in"),
new KeyValuePair<string, string>(@"identity", username),
new KeyValuePair<string, string>(@"password", password),
new KeyValuePair<string, string>(@"remember", @"on"),
new KeyValuePair<string, string>(@"submit", @"Sign In"),
});
RequestResponse r = await PostRequest(@"/", content).ConfigureAwait(false);
Boolean cookieFound = false;
foreach (Cookie c in cookieJar.GetCookies(baseUri))
{
if (c.Name == @"ow_login")
{
cookieFound = true;
}
}
return cookieFound;
}