Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中处理来自事件委托的返回值?_C#_Events_Delegates_Return Value - Fatal编程技术网

如何在C#中处理来自事件委托的返回值?

如何在C#中处理来自事件委托的返回值?,c#,events,delegates,return-value,C#,Events,Delegates,Return Value,所以我自己也很好奇,因为我越是开发从事件中获取数据的更多用途,所以我四处看了看,发现在处理事件代表的响应方面没有太多的信息 有一个具有返回值的委托,并执行所述委托的方法,并获取其返回值是一回事,但是当一个事件引发大量委托时,您该怎么办?您如何确定每个学员的情况? 问答式- 因为关于这个主题的内容太少,而且内容太多样化,所以我选择了一些风格鲜明的东西——我认为这是一个相当彻底的“事件响应处理程序” 在下面的代码示例中(我刚刚用最新的格式副本更新了该示例(很可能还会更新),您将发现支持触发事件以及

所以我自己也很好奇,因为我越是开发从事件中获取数据的更多用途,所以我四处看了看,发现在处理事件代表的响应方面没有太多的信息

有一个具有返回值的委托,并执行所述委托的方法,并获取其返回值是一回事,但是当一个事件引发大量委托时,您该怎么办?您如何确定每个学员的情况?

  • 问答式-
因为关于这个主题的内容太少,而且内容太多样化,所以我选择了一些风格鲜明的东西——我认为这是一个相当彻底的“事件响应处理程序”

在下面的代码示例中(我刚刚用最新的格式副本更新了该示例(很可能还会更新),您将发现支持触发事件以及最终从随后执行的任何方法返回数据的代码。用于将数据传递给事件委托的“Event”类最终将包含一组EventResults,可在以后进行评估。这使开发人员能够在触发事件后响应失败的委托

第一个类是一个“事件”,它包含一些变量,这些变量可以向您的代理提供一些有价值的反馈,比如事件来自哪个对象、简单的字符串消息、关联的堆栈等

event类还包含“EventResponses”的集合;这就把我们带到了第二节课。。。事件响应。这个类有两个“类型”;可以为子执行提供即时反馈

这是如何通过EventResponse构造函数中“SourceEvent”的要求实现的;并通过执行“EventResponse.FinalizerResponse”方法,将事件响应添加到关联事件中。我刚刚完成将EventResponse修改为一次性的,在处理过程中,我检查EventResponse的SourceEvent,如果SourceEvent不包含我正在处理的EventResponse的条目,我将创建EventResponse的新副本,并在新副本上运行FinalizerResponse

所有这些的最终价值是广泛的-如果您注意到事件类中的一个事件,称为“OnResponseFailure”,类似地,事件上的“AddResponse”方法,您会注意到当一个事件遇到被视为“失败”的响应时;它自身抛出一个事件来潜在地通知初始调用方法

Event类还包含两个字段,可用于在执行所有委托后分析响应内部的失败或成功;我会留下来让你慢慢走过

类似地,EventResponse类包含几个字段,如果有必要,可以使用这些字段将更多数据返回到启动事件的方法,例如响应的源对象和消息

我希望这是一个有用的问答,因为我觉得它将极大地帮助我创建健壮、响应迅速的代码。狩猎快乐

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace MyNamespace.Events
{
    public class EventDriver : IDisposable
    {
        #region Supporting Events
        public List<EventResponse> FireEvent(String EventName, Event Event)
        {
            List<EventResponse> ResponseList = new List<EventResponse>();

            Type LocalType = this.GetType();

            Type TargetType = null;

            if ((TargetType = this.FindEventType(LocalType, EventName)) == null)
            {
                return ResponseList;
            }
            else
            {
                FieldInfo TargetField = TargetType.GetField(EventName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

                MulticastDelegate EventDelegates = (MulticastDelegate) TargetField.GetValue(this);

                if (EventDelegates == null)
                {
                    return ResponseList;
                }
                else
                {
                    foreach (Delegate TargetDelegate in EventDelegates.GetInvocationList())
                    {
                        try
                        {
                            Object DelegateResponse = TargetDelegate.DynamicInvoke(new Object[] { Event });
                            EventResponse Response = (EventResponse)DelegateResponse;
                            ResponseList.Add(Response);
                        }
                        catch (Exception e)
                        {
                        }
                    }

                    return ResponseList;
                }
            }
        }

        private Type FindEventType(Type RootType, String EventName)
        {
            if (RootType == null)
            {
                return null;
            }
            else if (String.IsNullOrEmpty(EventName))
            {
                return null;
            }
            else
            {
                FieldInfo EventField = null;

                foreach (FieldInfo Method in RootType.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
                    if (Method.Name == EventName)
                    {
                        EventField = Method;
                        break;
                    }

                if (EventField == null)
                {
                    if (RootType.BaseType == null)
                        return null;
                    else
                        return this.FindEventType(RootType.BaseType, EventName);
                }
                else
                {
                    return RootType;
                }
            }
        }
        #endregion

        #region Dispoability
        public virtual void Dispose()
        {
            this.FireEvent("OnDispose", new Event(this, "Object is being disposed."));
        }
        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Reflection;

namespace MyNamespace.Events
{
    #region Delegates
    public delegate EventResponse EventHandler(Event Event);
    #endregion

    #region Enumerations
    public enum EventResponseType
    {
        Success, Failure
    }
    #endregion

    public class Event
    {
        #region Events
        public event EventHandler OnResponseFailure = null;
        #endregion

        #region Fields
        public Object EventSource = null;

        public DateTime EventTime = DateTime.Now;

        public String EventMessage = String.Empty;

        protected StackTrace _EventStackTrace = null;

        public StackTrace EventStackTrace
        {
            get
            {
                return this._EventStackTrace;
            }
        }

        protected List<EventResponse> _EventResponses = null;

        public List<EventResponse> EventResponses
        {
            get
            {
                List<EventResponse> EventResponses = new List<EventResponse>();

                lock (this._EventResponses)
                {
                    foreach (EventResponse Response in this._EventResponses)
                        EventResponses.Add(Response);
                }

                return EventResponses;
            }
        }

        public Boolean HasFailedResponses
        {
            get
            {
                if (this.FailedResponses.Count > 0)
                    return true;
                return false;
            }
        }

        public Boolean HasSuccessfulResponses
        {
            get
            {
                if (this.SucceessfulResponses.Count > 0)
                    return true;
                return false;
            }
        }

        public List<EventResponse> FailedResponses
        {
            get
            {
                List<EventResponse> FailedResponses = new List<EventResponse>();

                foreach (EventResponse Response in this.EventResponses)
                    if (Response.ResponseType == EventResponseType.Failure)
                        FailedResponses.Add(Response);
                return FailedResponses;
            }
        }

        public List<EventResponse> SucceessfulResponses
        {
            get
            {
                List<EventResponse> SucceededResponses = new List<EventResponse>();

                foreach (EventResponse Response in this.EventResponses)
                    if (Response.ResponseType == EventResponseType.Success)
                        SucceededResponses.Add(Response);
                return SucceededResponses;
            }
        }

        protected List<Event> _ForwardedEvents = null;

        public List<Event> ForwardedEvents
        {
            get
            {
                List<Event> FowardedEvents = new List<Event>();

                lock (this._ForwardedEvents)
                    foreach (Event ForwardedEvent in this.ForwardedEvents)
                        ForwardedEvents.Add(ForwardedEvent);

                return ForwardedEvents;
            }
        }
        #endregion

        #region Constructors
        protected Event()
        {
            this._EventResponses = new List<EventResponse>();
            this._EventStackTrace = new StackTrace();
            this._ForwardedEvents = new List<Event>();
        }

        public Event(Object EventSource, String EventMessage, DateTime EventTime)
            : this()
        {
            this.EventSource = EventSource;
            this.EventTime = EventTime;
            this.EventMessage = EventMessage;

            return;
        }

        public Event(Object EventSource, String EventMessage)
            : this(EventSource, EventMessage, DateTime.Now)
        {
        }
        #endregion

        #region Supporting Methods
        public void AddResponse(EventResponse Response)
        {
            lock (this._EventResponses)
            {
                this._EventResponses.Add(Response);
            }

            if (Response.ResponseType == EventResponseType.Failure)
                this.TriggerResponseFailure(Response);

            return;
        }

        public EventResponse CreateResponse()
        {
            return new EventResponse(this);
        }

        public EventResponse CreateResponse(Object ResponseSource, Object ResponseObject, DateTime ResponseTime, String ResponseMessage, EventResponseType ResponseType)
        {
            return new EventResponse(this, ResponseSource, ResponseObject, ResponseTime, ResponseMessage, ResponseType);
        }

        public EventResponse CreateResponse(Object ResponseSource, Object ResponseObject, DateTime ResponseTime, EventResponseType ResponseType)
        {
            return this.CreateResponse(ResponseSource, ResponseObject, ResponseTime, String.Empty, ResponseType);
        }

        public EventResponse CreateResponse(Object ResponseSource, Object ResponseObject, DateTime ResponseTime)
        {
            return this.CreateResponse(ResponseSource, ResponseObject, ResponseTime, EventResponseType.Success);
        }

        public EventResponse CreateResponse(Object ResponseSource, Object ResponseObject, EventResponseType ResponseType)
        {
            return this.CreateResponse(ResponseSource, ResponseObject, DateTime.Now, ResponseType);
        }

        public EventResponse CreateResponse(Object ResponseSource, Object ResponseObject)
        {
            return this.CreateResponse(ResponseSource, ResponseObject, EventResponseType.Success);
        }

        public EventResponse CreateResponse(Object ResponseSource, String ResponseMessage)
        {
            return this.CreateResponse(ResponseSource, null, DateTime.Now, ResponseMessage, EventResponseType.Success);
        }

        public EventResponse CreateResponse(String ResponseMessage)
        {
            return this.CreateResponse(null, ResponseMessage);
        }

        public EventResponse CreateResponse(Object ResponseSource)
        {
            return this.CreateResponse(ResponseSource, String.Empty);
        }

        public Event Forward(Object ForwardFrom)
        {
            Event ForwardedEvent = new Event(ForwardFrom, this.EventMessage, this.EventTime);

            lock (this._ForwardedEvents)
                this._ForwardedEvents.Add(ForwardedEvent);

            return ForwardedEvent;
        }
        #endregion

        #region Event Triggers
        protected void TriggerResponseFailure(EventResponse Response)
        {
            if (this.OnResponseFailure != null)
                this.OnResponseFailure(new Event(Response, "A failure was encountered while executing this event."));
            return;
        }
        #endregion
    }

    public class EventResponse : IDisposable
    {
        #region Fields
        protected Event _SourceEvent = null;

        public Event SourceEvent
        {
            get
            {
                return this._SourceEvent;
            }
        }

        public Object ResponseSource = null;

        public Type ResponseSourceType
        {
            get
            {
                return this.ResponseSource.GetType();
            }
        }

        public Object ResponseObject = null;

        public Type ResponseObjectType
        {
            get
            {
                return this.ResponseObject.GetType();
            }
        }

        public DateTime ResponseTime = DateTime.Now;

        public String ResponseMessage = String.Empty;

        protected StackTrace _ResponseStackTrace = null;

        public StackTrace ResponseStackTrace
        {
            get
            {
                return this._ResponseStackTrace;
            }
        }

        public EventResponseType ResponseType = EventResponseType.Success;
        #endregion

        #region Constructors
        public EventResponse(Event SourceEvent)
        {
            this._SourceEvent = SourceEvent;

            this._ResponseStackTrace = new StackTrace();
        }

        public EventResponse(Event SourceEvent, Object ResponseSource, Object ResponseObject, DateTime ResponseTime, String ResponseMessage, EventResponseType ResponseType)
            : this(SourceEvent)
        {
            this.ResponseSource = ResponseSource;
            this.ResponseObject = ResponseObject;
            this.ResponseTime = ResponseTime;
            this.ResponseMessage = ResponseMessage;
            this.ResponseType = ResponseType;

            return;
        }

        public EventResponse(Event SourceEvent, Object ResponseSource, Object ResponseObject, DateTime ResponseTime, EventResponseType ResponseType)
            : this(SourceEvent,ResponseSource,ResponseObject,ResponseTime,String.Empty,ResponseType)
        {
        }

        public EventResponse(Event SourceEvent, Object ResponseSource, Object ResponseObject, DateTime ResponseTime)
            : this(SourceEvent, ResponseSource, ResponseObject, ResponseTime, EventResponseType.Success)
        {
        }

        public EventResponse(Event SourceEvent, Object ResponseSource, Object ResponseObject, EventResponseType ResponseType)
            : this(SourceEvent, ResponseSource, ResponseObject, DateTime.Now, ResponseType)
        {
        }

        public EventResponse(Event SourceEvent, Object ResponseSource, Object ResponseObject)
            : this(SourceEvent, ResponseSource, ResponseObject, EventResponseType.Success)
        {
        }

        public EventResponse(Event SourceEvent, Object ResponseSource, EventResponseType ResponseType)
            : this(SourceEvent, ResponseSource, null, DateTime.Now, String.Empty, ResponseType)
        {

        }

        public EventResponse(Event SourceEvent, Object ResponseSource, String ResponseMessage)
            : this(SourceEvent, ResponseSource, null, DateTime.Now, ResponseMessage, EventResponseType.Success)
        {

        }

        public EventResponse(Event SourceEvent, String ResponseMessage)
            : this( SourceEvent, null, ResponseMessage )
        {
        }
        #endregion

        #region Supporting Methods
        public void FinalizeResponse()
        {
            this.SourceEvent.AddResponse(this);
            return;
        }
        #endregion

        #region Overrides
        public void Dispose()
        {
            if (this.SourceEvent == null)
                return;
            else if (this.SourceEvent.EventResponses.Contains(this))
                return;
            else
            {
                EventResponse NewResponse = new EventResponse(this.SourceEvent, this.ResponseSource, this.ResponseObject, this.ResponseTime, this.ResponseMessage, this.ResponseType);
                NewResponse.FinalizeResponse();
                return;
            }
        }
        #endregion
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
运用系统反思;
名称空间MyNamespace.Events
{
公共类事件驱动程序:IDisposable
{
#区域支持活动
公共列表FireEvent(字符串EventName,事件)
{
列表响应列表=新列表();
Type LocalType=this.GetType();
类型TargetType=null;
if((TargetType=this.FindEventType(LocalType,EventName))==null)
{
返回应答器;
}
其他的
{
FieldInfo TargetField=TargetType.GetField(事件名称,BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
MulticastDelegate EventDelegates=(MulticastDelegate)TargetField.GetValue(此);
if(EventDelegates==null)
{
返回应答器;
}
其他的
{
foreach(EventDelegates.GetInvocationList()中的委托TargetDelegate)
{
尝试
{
objectdelegateresponse=TargetDelegate.DynamicInvoke(新对象[]{Event});
EventResponse=(EventResponse)DelegateResponse;
响应列表。添加(响应);
}
捕获(例外e)
{
}
}
返回应答器;
}
}
}
私有类型FindEventType(类型RootType,字符串EventName)
{
if(RootType==null)
{
返回null;
}
else if(String.IsNullOrEmpty(EventName))
{
返回null;
}
其他的
{
FieldInfo EventField=null;
foreach(RootType.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)中的FieldInfo方法)
if(Method.Name==EventName)
{
EventField=方法;
打破
}
if(EventField==null)
{
if(RootType.BaseType==null)
返回null;
其他的
返回此.FindEventType(RootType.BaseType,EventName);
}
其他的
{
返回根类型;
}
}
}
#端区
#区域Di
public delegate object GetObject();
public event GetObject MyEvent;

public IList<object> RaiseMyEvent()
{
    var myList = new List<object>();
    if (MyEvent != null)
        foreach (var handler in MyEvent.GetInvocationList())
            myList.Add(handler.DynamicInvoke());
    return myList;
}