a.t*_*aby 6 c# events async-await
在我的代码中,我需要取消注册并注册一个事件处理程序,这非常有效:
_favoritsImageView.Click -= _favoritsImageView_Click(this, new CustomeClickEventArgs(item));
_favoritsImageView.Click += _favoritsImageView_Click(this, new CustomeClickEventArgs(item));
void _favoritsImageView_Click(object sender, CustomeClickEventArgs e)
{
// handles the event
}
Run Code Online (Sandbox Code Playgroud)
但对于一个等待的事件处理程序,我必须使用以下语法:
_favoritsImageView.Click -= async (s, e) =>
{ await _favoritsImageView_ClickAsync(s, new CustomeClickEventArgs(item)); };
_favoritsImageView.Click += async (s, e) =>
{ await _favoritsImageView_ClickAsync(s, new CustomeClickEventArgs(item)); };
async Task _favoritsImageView_ClickAsync(object sender, CustomeClickEventArgs e)
{
// does async task
}
Run Code Online (Sandbox Code Playgroud)
这不起作用.因为匿名方法没有相同的引用.因此第一行不会取消注册已注册的处理程序.最后,第二行为点击添加了额外的事件处理程序.
我需要使用哪种语法来添加和删除异步事件处理程序?
谢谢你的任何建议.
我需要使用哪种语法来添加和删除异步事件处理程序?
与常规事件处理程序一起使用的语法相同.您需要将委托保存在某处,以便以后可以取消注册:
private EventHandler eventHandler =
new EventHandler(async (s, e) => await FooAsync(s, e));
public async void SomeOtherEventHandler()
{
var m = new M();
m.X += eventHandler;
m.OnFoo();
m.X -= eventHandler;
m.OnFoo();
}
public async Task FooAsync(object sender, EventArgs e)
{
await Task.Delay(1000);
Debug.WriteLine("Yay event handler");
}
public class M
{
public event EventHandler X;
public void OnX()
{
// If you're using C#-6, then X?.Invoke(null, EventArgs.Empty);
var localX = X;
if (localX != null)
localX(null, EventArgs.Empty);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
@svick建议或许另一个解决方案,简单地制作方法async void并直接注册它,这肯定更短:
public async void SomeOtherEventHandler()
{
var m = new M();
m.X += FooAsync;
m.OnFoo();
m.X -= FooAsync;
m.OnFoo();
}
public async void FooAsync(object sender, EventArgs e)
{
await Task.Delay(1000);
Debug.WriteLine("Yay event handler");
}
Run Code Online (Sandbox Code Playgroud)
同步代码如下所示:
private void FavoritsImageView_Click(object sender, CustomeClickEventArgs args)
{
// your synchronous code here
}
…
_favoritsImageView.Click += FavoritsImageView_Click;
_favoritsImageView.Click -= FavoritsImageView_Click;
Run Code Online (Sandbox Code Playgroud)
该async版本看起来几乎是相同的,你只需要添加async的方法:
private async void FavoritsImageView_Click(object sender, CustomeClickEventArgs args)
{
// your asynchronous code here
}
…
_favoritsImageView.Click += FavoritsImageView_Click;
_favoritsImageView.Click -= FavoritsImageView_Click;
Run Code Online (Sandbox Code Playgroud)
请注意,事件处理程序几乎是您应该使用的唯一地方async void。在大多数其他情况下,同步void方法应该转换为async Task方法。
| 归档时间: |
|
| 查看次数: |
1721 次 |
| 最近记录: |