取消订阅 C# 上 Webclient 事件的处理程序?
Unsubscribe handler on Webclient event on C#?
我想实现一种负责将我的 Web 客户端订阅到处理程序的方法,当我想取消订阅时,它似乎没有正确完成。
我有一个例子:
我的函数用于订阅
private void SendRequest(Action<object, UploadStringCompletedEventArgs> callback, string url)
{
if (!wClient.IsBusy)
{
wClient.UploadStringCompleted += new UploadStringCompletedEventHandler(callback);
wClient.UploadStringAsync(new Uri(url), "POST");
[...]
}
}
我的处理人员
private void wClient_request1Completed(object sender, UploadStringCompletedEventArgs e)
{
wClient.UploadStringCompleted -= wClient_request1Completed;
[...]
}
private void wClient_request2Completed(object sender, UploadStringCompletedEventArgs e)
{
wClient.UploadStringCompleted -= wClient_request2Completed;
[...]
}
并且我像这样使用这些方法
private WebClient wClient = new WebClient();
SendRequest(wClient_request1Completed, myUrl1);
// wClient_request1Completed(..) is run successfully
[... Request 1 is already completed ...]
SendRequest(wClient_request2Completed, myUrl2);
// wClient_request1Completed(..) and wClient_request2Completed(..) are run
你知道我的问题吗?
非常感谢!
那是因为您隐式创建了一个新委托作为 SendRequest
方法的参数。基本上,您当前的代码可以重写为:
// Done implicitly by the compiler
var handler = new Action<object, UploadStringCompletedEventArgs>(wClient_request1Completed);
wClient.UploadStringCompleted += handler;
// ...
wClient.UploadStringCompleted -= wClient_request1Completed // (instead of handler)
修复它的一种方法是使用 UploadStringAsync
方法的有效负载参数来保留对处理程序的引用:
var handler = new UploadStringCompletedEventHandler(callback);
wClient.UploadStringCompleted += handler;
wClient.UploadStringAsync(new Uri(url), "POST", null, handler);
然后,在 UploadStringCompleted
事件中:
private void wClient_request1Completed(object sender, UploadStringCompletedEventArgs e)
{
var handler = (UploadStringCompletedEventHandler)e.UserState;
wClient.UploadStringCompleted -= handler ;
[...]
}
也就是说,您应该考虑切换到 HttpClient
和 async/await 编程模型,因为这会使您的代码更容易理解。
我想实现一种负责将我的 Web 客户端订阅到处理程序的方法,当我想取消订阅时,它似乎没有正确完成。 我有一个例子:
我的函数用于订阅
private void SendRequest(Action<object, UploadStringCompletedEventArgs> callback, string url)
{
if (!wClient.IsBusy)
{
wClient.UploadStringCompleted += new UploadStringCompletedEventHandler(callback);
wClient.UploadStringAsync(new Uri(url), "POST");
[...]
}
}
我的处理人员
private void wClient_request1Completed(object sender, UploadStringCompletedEventArgs e)
{
wClient.UploadStringCompleted -= wClient_request1Completed;
[...]
}
private void wClient_request2Completed(object sender, UploadStringCompletedEventArgs e)
{
wClient.UploadStringCompleted -= wClient_request2Completed;
[...]
}
并且我像这样使用这些方法
private WebClient wClient = new WebClient();
SendRequest(wClient_request1Completed, myUrl1);
// wClient_request1Completed(..) is run successfully
[... Request 1 is already completed ...]
SendRequest(wClient_request2Completed, myUrl2);
// wClient_request1Completed(..) and wClient_request2Completed(..) are run
你知道我的问题吗? 非常感谢!
那是因为您隐式创建了一个新委托作为 SendRequest
方法的参数。基本上,您当前的代码可以重写为:
// Done implicitly by the compiler
var handler = new Action<object, UploadStringCompletedEventArgs>(wClient_request1Completed);
wClient.UploadStringCompleted += handler;
// ...
wClient.UploadStringCompleted -= wClient_request1Completed // (instead of handler)
修复它的一种方法是使用 UploadStringAsync
方法的有效负载参数来保留对处理程序的引用:
var handler = new UploadStringCompletedEventHandler(callback);
wClient.UploadStringCompleted += handler;
wClient.UploadStringAsync(new Uri(url), "POST", null, handler);
然后,在 UploadStringCompleted
事件中:
private void wClient_request1Completed(object sender, UploadStringCompletedEventArgs e)
{
var handler = (UploadStringCompletedEventHandler)e.UserState;
wClient.UploadStringCompleted -= handler ;
[...]
}
也就是说,您应该考虑切换到 HttpClient
和 async/await 编程模型,因为这会使您的代码更容易理解。