【发布时间】:2016-11-23 11:21:40
【问题描述】:
我正在使用 Xamarin 在 C# 中做一个项目。编译器警告我“异步方法 'HandleWidget_ClickButton' 不应返回 void”。请参阅此处的示例:
//Code is simplified
public class Widget {
public event Action<int> ClickButton;
private void FireClickButton (int id)
{
if (ClickButton != null) {
ClickButton (id);
}
}
//somewhere else i call FireClickButton(1);
}
public class MyFragment {
private _widget Widget;
public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
//...
_widget = view.FindViewById<Widget> (Resource.Id.widget);
//...
}
public override void OnResume ()
{
base.OnResume ();
_widget.ClickButton += HandleWidget_ClickButton;
}
async void HandleWidget_ClickButton (int id)
{
await SaveSomethingInStorage (id);
}
}
我能否以某种方式将某些内容返回给事件/动作/委托?我不知道这是否可能,或者如何在语法方面编写它,并且我花了相当长的时间寻找解决方案。在其他地方我读到,在处理事件时,可以使用 async void(而不是 async Task 之类的东西),但我喜欢避免警告,也不喜欢使用 #Pragma 指令隐藏它们。
编辑(有答案)来自@hvd:
您创建了一个事件处理程序,但您没有遵循 .NET 事件处理程序的约定。你应该。警告是 自动抑制可检测为事件处理程序的内容。
事件处理程序的 .NET 约定需要发送者,类型为 对象和事件参数,类型为 EventArgs 或派生类 来自 EventArgs。如果您使用此签名,则不应再获得 警告。
我这样重写了我的代码:
public class MyEventArgs : EventArgs
{
public MyEventArgs (int id)
{
ID = id;
}
public int ID;
}
public class Widget {
public event EventHandler<MyEventArgs> ClickTest;
void FireClickButton (int id)
{
if (ClickTest != null) {
ClickTest (this, new MyEventArgs (id));
}
}
}
//In observer class
_widget.ClickTest += HandleWidget_ClickTest;
async void HandleWidget_ClickTest (object sender, MyEventArgs e)
{
await DoSomethingAsync (e.ID);
}
请注意,您必须从 EventArgs 派生。这样做不会抑制警告:
public event EventHandler<int> AnotherClickTest;
if (AnotherClickTest != null) {
AnotherClickTest (this, 1);
}
【问题讨论】:
-
您可以改为返回
Task。但事件处理程序是该规则的例外 - msdn.microsoft.com/en-us/magazine/jj991977.aspx -
另外,看看这个问题 - stackoverflow.com/questions/27282617/…
标签: c# asynchronous