我有以下内容:
public String AttachService(string whereClauseParam)
{
//Get Client object here
Client c = new Client();
string cookieFromRequest = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Cookie];
tokenInfo.TryGetValue(cookieFromRequest, out c);
string[] arr = new string[] { };
c.AttachedServiceStatus += OnAttachedServiceStatus;
string whereClause = whereClauseParam.ToString();
//c.AttachService("binding.interface='query_em'", 8799989);
return string.Format("attached");
}
//下面的处理程序代码:
public string OnAttachedServiceStatus(Client sender, ClientServiceAttachedStatus status)
{
if (status.AttachStatus == AttachedStatus.Connected && status.ServiceAttachStatus == ServiceAttachStatus.Attached)
{
//update the Client object in Dictionary
Client c = new Client();
var ou = tokenInfo.First(x => x.Value == sender);
tokenInfo.TryGetValue(ou.Key.ToString(), out c);
tokenInfo.TryRemove(ou.Key.ToString(), out c);
tokenInfo.TryAdd(ou.Key.ToString(), sender);
string[] statusInfoT = new string[200];
statusInfoT[0] = status.ServiceId.ToString();
statusInfoT[1] = status.AttachStatus.ToString();
statusInfoT[2] = status.ServiceAttachStatus.ToString();
statusInfoT[3] = status.VirtualServiceId.ToString();
statusInfoT[4] = status.AttachToken.ToString();
statusInfo.TryAdd(ou.Key.ToString(), statusInfoT);
//update the UI with a Dispatch - TO BE DONE
}
return "Connected";
}
上面的AttachService方法有一个处理程序" OnAttachedServiceStatus"附加到事件" AttachedServiceStatus"。 只要OnAttachedServiceStatus返回void,它就可以正常工作。但是,我现在需要让Handler OnAttachedServiceStatus返回一个字符串,但我无法正确附加处理程序。
我正在考虑使用Func委托,但不确定如何使用它。 请帮助!
答案 0 :(得分:1)
首先,事件处理程序的签名由事件的委托类型定义。如果该委托返回void
,则您无法附加任何其他方法。方法和返回值的参数都应该匹配偶数委托的签名。我相信AttachedServiceStatus
使用返回void
的委托。这样的事情:
public delegate void Action<T1, T2>(T1 arg1, T2 arg2)
事件是
public event Action<Client, ClientServiceAttachedStatus> AttachedServiceStatus
但是,如果你将使用返回值的委托怎么办? E.g。
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2)
您可以将事件声明为
public event Func<Client, ClientServiceAttachedStatus> AttachedServiceStatus
但这没有任何意义。因为事件是代表。当您附加处理程序时,您实际上是在组合委托,创建类似委托列表(调用列表)之类的东西。此列表包含所有附加的处理程序。当您引发事件时,将逐个调用调用列表中的所有处理程序,并且仅返回上次调用的处理程序的结果。调查顺序未确定。所以你甚至不知道哪个处理程序返回了值。
(*)虽然如果你手动调用每个处理程序而不是引发事件,仍然可以获得所有结果。请参阅下面的Servy评论
更新
我希望处理程序“OnAttachedServiceStatus”返回一个字符串 到来电者“AttachService”,但我无法得到以下正确的
将事件附加到事件时,不执行处理程序。它刚刚添加到事件的调用列表中。当Client
引发事件时,将执行事件处理程序。所以AttachService
不是来电者。 Client
是来电者。而且你不能将字符串返回AttachService
。将处理程序附加到事件后,代码将退出AttachService
方法。一段时间之后将引发事件,并且将执行处理程序,但它与AttachService
方法无关。
答案 1 :(得分:0)
我不确定你是否了解事件是如何运作的。
Client c = new Client();
// ...
c.AttachedServiceStatus += OnAttachedServiceStatus;
此处未调用OnAttachedServiceStatus。相反,这告诉Client对象在引发AttachedServiceStatus事件时调用OnAttachedServiceStatus方法,这可能发生在将来的任何时候。这就像你告诉赛车手一样#34;当我说'去'时,尽可能快地跑到终点线然后告诉我你到达那里需要多少步骤&#34 ;。赛车手并没有立即开始跑步,他们也没有告诉你它采取了多少步骤;他们处于准备状态并等待。当你说&#34;去&#34;,当他们执行你的指示并开始跑步时。当你得到他们的回复时,在你给他等待的指示之后,这很好。
从外观上看,您正在尝试建立远程连接,并且希望从服务器确认确实已建立连接。如果使用事件来传达该信息,您将要使用EventArgs来传递它。您应该能够通过以下方式实现这一目标:
客户方:
public String ConnectToServer(string whereClauseParam)
{
//Create Server object here
Server s = new Server();
s.AttachedServiceStatus += OnAttachedServiceStatus;
s.AttachService(this, whereClauseParam, 8799989);
}
public void OnAttachedServiceStatus (object sender, ClientServiceAttachedEventArgs e)
{
if (e.AttachStatus == AttachedStatus.Connected && e.ServiceAttachStatus == ServiceAttachStatus.Attached)
{
// Update the UI with the message from the server.
MessageBox.Show(e.Message);
// If you need to do something else with the server in response, you can do this:
((Server)sender).Foo("bar");
}
}
在服务器端,为您的活动定义自定义EventArgs类:
// By making this inherit from EventArgs, we can use the built-in EventHandler<T> delegate for the event itself.
public class ClientServiceAttachedEventArgs : EventArgs
{
public AttachedStatus AttachStatus { get; set; }
public ServiceAttachStatus ServiceAttachStatus { get; set; }
public string Message { get; set; }
// You can put in as many properties as you want to carry the information back from the server.
}
并将其放入您的Server类:
public event EventHandler<ClientServiceAttachedEventArgs> AttachedServiceStatus;
public String AttachService(Client client, string whereClauseParam, int code)
{
// Do what you need to do to register the client.
//...
// Assuming everything went as planned, fire the event.
// First, construct the EventArgs with information about the results of the connection.
ClientServiceAttachedEventArgs e = new ClientServiceAttachedEventArgs();
e.AttachStatus = AttachedStatus.Connected;
e.ServiceAttachStatus = ServiceAttachStatus.Attached;
e.Message = "Attached";
// This is where your OnAttachedServiceStatus method in the client finally gets called. If the event handler were returning a string, this is where it would be returned to and I can't imagine this does you any good.
AttachedServiceStatus(this, e);
}
这是一个相当基本的实现,您的情况可能更复杂,但它应该指向正确的方向。需要注意的重要一点是,您希望返回给客户端的字符串将作为ClientServiceAttachedEventArgs的一部分与您的状态枚举一起通过该事件。这是通过事件发送信息的首选方式。