C# 从一个事件返回一个值——这有好的实践吗?
我正在开发一个使用异步TCP套接字的小型多线程应用程序,但我要说的是:我正在使用一个自定义事件从表单读取一个值,事件使用的委托在完成时返回一个字符串C# 从一个事件返回一个值——这有好的实践吗?,c#,multithreading,events,delegates,C#,Multithreading,Events,Delegates,我正在开发一个使用异步TCP套接字的小型多线程应用程序,但我要说的是:我正在使用一个自定义事件从表单读取一个值,事件使用的委托在完成时返回一个字符串 我的问题是:这是正确的吗?可以从事件返回值吗?还是有更好的方法?(就像使用表单的简单委托读取值)我能想到的最接近的例子是WinForms中的FormClosing事件。它允许窗体通过将eventArgs.cancel属性设置为true来取消事件。若要执行类似的操作,可以使用返回值定义自己的event args类作为该类的属性。然后在引发事件时传递事
我的问题是:这是正确的吗?可以从事件返回值吗?还是有更好的方法?(就像使用表单的简单委托读取值)我能想到的最接近的例子是WinForms中的FormClosing事件。它允许窗体通过将eventArgs.cancel属性设置为true来取消事件。若要执行类似的操作,可以使用返回值定义自己的event args类作为该类的属性。然后在引发事件时传递事件args对象。引发事件的人可以检查事件args对象的返回值。接收事件的其他人也可以检查或更改事件args对象
更新:我刚刚运行了该事件,它似乎是一个返回值的事件。似乎您只需要声明一个返回值的委托类型,然后用该委托类型定义事件。不过,我还没有尝试过创建这样的活动。在事件参数上使用属性的一个优点是,事件的所有订阅者都可以看到以前的订阅者返回的内容。从事件中返回值通常比较麻烦。在实践中,我发现在传递给事件的一组自定义EventArg上包含一个可写属性,然后在事件激发后检查它要容易得多——类似于WinForms FormClosing事件的Cancel属性。我认为这不是一个好主意。。。事件基本上是多播委托,因此可以有多个处理程序。在这种情况下,您将采用哪个返回值?我不知道这是否是最佳做法,但我是这样做的
Func<DataRow, bool> IsDataValid;
// some other code ....
isValid = true;
if (IsDataValid != null)
{
foreach (Func<DataRow, bool> func in IsDataValid.GetInvocationList())
{
isValid &= func(Row);
}
}
Func IsDataValid;
//其他一些代码。。。。
isValid=true;
如果(IsDataValid!=null)
{
foreach(IsDataValid.GetInvocationList()中的Func Func)
{
isValid&=func(行);
}
}
无效方法()
{
列表字符串=新列表();
dostuff+=材料;
dostuff+=材料;
dostuff(这是新的EventHandlerArgs(){Parameter=strings})
foreach(字符串中的字符串currString)
{
//....
}
}
void stuff(对象发送器,EventHandlerArgs e)
{
列表字符串=e.参数为列表;
if(字符串!=null)
{
strings.Add(MyString)
}
}
我知道这篇文章已经发表很久了,但我想用代码添加注释,解释达斯汀·坎贝尔(Dustin Campbell)在别人遇到这篇文章时的回答。我是在决定什么是最佳实践时看到这篇文章的,这就是答案的意思
创建自己的自定义事件处理程序类
public class myCustomeEventArgs:EventArgs
{
public bool DoOverride { get; set; }
public string Variable1 { get; private set; }
public string Variable2{ get; private set; }
public myCustomeEventArgs(string variable1 , string variable2 )
{
DoOverride = false;
Variable1 = variable1 ;
Variables = variable2 ;
}
}
因此,当您创建事件委托时,可以像下面这样使用您创建的事件参数
public delegate void myCustomeEventHandler(object sender, myCustomeEventArgs e);
在引发事件的类中,您声明了事件
public event myCustomeEventHandler myCustomeEvent;
因此,当您在类中触发事件时,侦听事件的类可以在事件体中设置e.DoOverride=true;它将在触发事件的类中声明
public event myCustomeEventHandler myCustomeEvent;
火灾事件,例如:
if(myCustomeEvent != null)
{
var eventArgs = new myCustomeEventArgs("Some Variable", "Another Varaible");
myCustomeEvent(this, eventArgs);
//Here you can now with the return of the event work with the event args
if(eventArgs.DoOverride)
{
//Do Something
}
}
如果事件返回一个值,并且注册了多个处理程序,则事件将返回上次调用的处理程序的结果值。
在中查找示例注意:只有最后一个事件返回结果
class Program
{
static event Func<string, bool> TheEvent;
static void Main(string[] args)
{
TheEvent += new Func<string, bool>(Program_TheEvent);
TheEvent +=new Func<string,bool>(Program_TheEvent2);
TheEvent += new Func<string, bool>(Program_TheEvent3);
var r = TheEvent("s"); //r == flase (Program_TheEvent3)
}
static bool Program_TheEvent(string arg)
{
return true;
}
static bool Program_TheEvent2(string arg)
{
return true;
}
static bool Program_TheEvent3(string arg)
{
return false;
}
}
类程序
{
静态事件函数事件;
静态void Main(字符串[]参数)
{
事件+=新函数(程序事件);
事件+=新函数(程序事件2);
事件+=新功能(程序事件3);
var r=TheEvent(“s”);//r==flase(Program\u TheEvent3)
}
静态布尔程序事件(字符串参数)
{
返回true;
}
静态布尔程序\u TheEvent2(字符串arg)
{
返回true;
}
静态布尔程序\u TheEvent3(字符串arg)
{
返回false;
}
}
我像这样遍历EventArg的属性,并提取其X和Y值
private void navBarControl1\u单击(对象发送方,事件参数e)
{
int x=0;
int _y=0;
类型t=e.GetType();
IList props=新列表(t.GetProperties());
foreach(PropertyInfo props in props)
{
如果(道具名称=“X”)
{
对象propValue=prop.GetValue(e,null);
_x=转换为32(propValue);
}
如果(道具名称=“Y”)
{
对象propValue=prop.GetValue(e,null);
_y=转换为32(propValue);
}
}
能否请您详细说明在传递给事件部分的一组自定义EventArgs上包含一个可写属性?@Odys使EventArgument对象自定义。创建一个结果存在的属性。欢迎使用stackoverflow!最好提供一个示例代码的简短描述,以提高post准确性:)注意:您可以使用任何委托来定义事件,因此也可以定义类似于public event Func SomeEvent;
的事件,该事件可调用为bool r=SomeEvent(“foo”、“bar”);
谢谢。适用于我的WCF服务如何知道事件何时“返回”?事件在引发它们的同一线程上运行。运行myCustomeEvent(…)
的代码将把控制权(在同一线程上运行)传递给所有订阅的事件处理程序。一旦它们的所有代码都已运行,则控制权将在调用myCusomeEvent(…)后立即返回指令
。如果没有订阅者,或者有订阅者将事件重新广播到另一个线程上,则eventArgs
上的所有属性都将有其默认值(对于bool
为false,对于字符串为null
)。回答中的链接无效-“未找到页面”。