【发布时间】:2018-08-10 23:01:31
【问题描述】:
在我的 WinForms 应用程序中,我想在它与 webApi 交互时查看原始请求/响应数据。我需要在 UI RichTextBoxes 中显示请求/响应。为此,我将 HttpClient 设置如下:
private HttpClient client;
private void CreateService()
{
client = new HttpClient(new LoggingHandler(new HttpClientHandler(), this))
{
BaseAddress = new Uri(this._URI)
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
我的日志处理程序:
public class LoggingHandler : DelegatingHandler
{
private SimplySignRestClientAsync _client;
public LoggingHandler(HttpMessageHandler innerHandler, SimplySignRestClientAsync client) : base(innerHandler)
{
this._client = client;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
string p_Request = "";
if (_client._updateRequest != null)
{
p_Request = request.ToString();
if (request.Content != null)
{
p_Request += "\n\nContent:\n" + FormatJsonString(await request.Content.ReadAsStringAsync());
}
//_client._request.Text = p_Request; << this works but causes a cross-thread exception in debug only
SetText(p_Request); << This deadlocks the UI
}
return response;
}
delegate void SetTextCallback(string text);
private void SetText(string text)
{
if (_client._request.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
_client._response.Invoke(d, new object[] { text });
}
else
{
_client._request.Text = text;
}
}
}
如果我尝试直接访问richtextbox,它仅在我执行应用程序而不调试时才有效。但是在调试过程中会出现跨线程异常。
这就是我调用 httpClient 的方式:
//This is how the original call gets initiated from UI
private void uiLogin_Click(object sender, EventArgs e)
{
Agent resp = Client.Login(new Credentials(uiUsername.Text, uiPassword.Text));
uiAuthToken.Text = Client.getAuthToken();
}
//this method has to stay synchronous, but it in turn calls an async method below
public Agent Login(Credentials loginInfo)
{
var task = Task.Run(async () => await LoginAsync(loginInfo));
return task.Result.Content; <<< this is where the application stops if i hit pause during debug when deadlock happens
}
//
async public Task<RestResponse<Agent>> LoginAsync(Credentials loginInfo)
{
HttpResponseMessage response = await client.PostAsJsonAsync(this._URI + "api/users/login", loginInfo);
var content = await response.Content.ReadAsStringAsync();
RestResponse<Agent> respAgent respAgent = JsonConvert.DeserializeObject<RestResponse<Agent>>(content);
return respAgent;
}
据我了解,我的“返回 task.Result.Content”会阻塞 UI 线程和“_client._response.Invoke(d, new object[] { text });”正在等待解除阻塞导致死锁。但我也不确定如何让调用等待。
【问题讨论】:
-
查看这里如何同步运行异步代码stackoverflow.com/questions/5095183/…
标签: c# multithreading winforms async-await