正确中止或取消 PostAsync
Posted
技术标签:
【中文标题】正确中止或取消 PostAsync【英文标题】:Properly Abort or Cancel PostAsync 【发布时间】:2014-05-28 19:58:31 【问题描述】:在使用 HttpClient 时是否有保证取消帖子的方法?我目前有一个调用 postAsync ,我试图使用 cancelToken 取消它,但它似乎实际上并没有中止/停止操作。我仍然可以看到我上传的图片已正确发布。
我在这里做错了什么,还是 HttpClient 可能在上传之后才处理取消令牌?
var sc = new StreamContent(uploadFile.Data);
content.Add(sc, uploadFile.FieldName, uploadFile.FileName);
var request = new HttpRequestMessage
RequestUri = new Uri(ApiImageUrlUpload),
Content = content
;
request.Headers.TryAddWithoutValidation("User-Agent", _sessionManager.UserAgent);
request.Headers.TransferEncodingChunked = true;
using(cancellationToken.Register(() => httpClient.CancelPendingRequests()))
httpResponse = await HttpClient.PostAsync(new Uri(ApiImageUrlUpload), content, cancellationToken);
【问题讨论】:
相关:Cancel an 'HttpClient' POST request 该相关问题没有与 HTTP 相关的答案。 【参考方案1】:您可以手动处理请求对象,该对象应抛出 ObjectDisposedException
并取消任何网络活动。
【讨论】:
Dispose 是否因为 GC 而不是真正的高性能?【参考方案2】:试试这个代码示例
public partial class LoginForm : MaterialForm
static NLog.Logger logger = LogManager.GetLogger("LoginForm");
HttpClient client;
HttpResponseMessage response;
public LoginForm()
InitializeComponent();
materialLabelErrMessage.Visible = false;
#region GUI events
private void BntCancel_Click(object sender, EventArgs e)
CancelLogin();
Close();
private void BtnOK_Click(object sender, EventArgs e)
Login();
private void TextBoxPassword_KeyDown(object sender, KeyEventArgs e)
if (e.KeyCode == Keys.Enter)
Login();
private void TextBoxUsername_KeyDown(object sender, KeyEventArgs e)
if (e.KeyCode == Keys.Enter)
Login();
#endregion
#region Keyboard Helpers
protected override bool ProcessDialogKey(Keys keyData)
if (Form.ModifierKeys == Keys.None && keyData == Keys.Escape)
CancelLogin();
Close();
return true;
return base.ProcessDialogKey(keyData);
#endregion
async void Login()
try
pbLogin.Visible = true;
btnOK.Enabled = false;
materialLabelErrMessage.Text = string.Empty;
materialLabelErrMessage.Visible = false;
client = new HttpClient();
var user = new User() Username = textBoxUsername.Text.Trim(), Password = StringUtils.Crypt(textBoxPassword.Text.Trim()) ;
var url = Properties.Settings.Default.ServerBaseUrl + @"/api/account/VerifyUserNamePassword";
response = await client.PostAsync(url, user.AsJson());
if (response.IsSuccessStatusCode) // Check the response StatusCode
var serSettings = new JsonSerializerSettings() TypeNameHandling = TypeNameHandling.All ;
string responseBody = await response.Content.ReadAsStringAsync();
var loggedUser = JsonConvert.DeserializeObject<User>(responseBody, serSettings);
if (loggedUser.IsLogged == false && loggedUser.UserId == Guid.Empty)
logger.Warn(Properties.Resources.LOGINUsernameOrPasswordWrong + " Username:" + user.Username);
BeginInvoke((Action)(() =>
materialLabelErrMessage.Text = Properties.Resources.LOGINUsernameOrPasswordWrong;
materialLabelErrMessage.Visible = true;
pbLogin.Visible = false;
btnOK.Enabled = true;
));
else
logger.Info(Properties.Resources.LOGINPassed + " Username:" + user.Username);
BeginInvoke((Action)(() =>
materialLabelErrMessage.Text = string.Empty;
materialLabelErrMessage.Visible = false;
Program.UserInfo = loggedUser;
DialogResult = DialogResult.OK;
pbLogin.Visible = false;
));
else if (response.StatusCode == HttpStatusCode.Forbidden)
pbLogin.Visible = false;
btnOK.Enabled = true;
materialLabelErrMessage.Text = Properties.Resources.LOGINUsernameOrPasswordWrong;
materialLabelErrMessage.Visible = true;
logger.Warn(Properties.Resources.LOGINUsernameOrPasswordWrong + " Username:" + user.Username);
else
pbLogin.Visible = false;
btnOK.Enabled = true;
materialLabelErrMessage.Text = Properties.Resources.LOGINCannotConnectToServer;
materialLabelErrMessage.Visible = true;
logger.Error("Reason: " + response.ReasonPhrase + " Message: " + response.RequestMessage + " Username:" + user.Username);
catch (ObjectDisposedException ex)
logger.Error("Login has been canceled. " + ex.Message);
pbLogin.Visible = false;
btnOK.Enabled = true;
catch (Exception ex)
logger.Error(Properties.Resources.LOGINUsernameOrPasswordWrong + " " + ex.Message);
pbLogin.Visible = false;
btnOK.Enabled = true;
void CancelLogin()
if (client != null)
client.CancelPendingRequests();
client = null;
【讨论】:
以上是关于正确中止或取消 PostAsync的主要内容,如果未能解决你的问题,请参考以下文章