如何在另一个类中定义事件处理程序?

时间:2019-01-12 18:24:58

标签: c#

我试图在类UploadStringCompleted之外定义Webclient的{​​{1}},所以我定义了一个变量PanelAPI

requestTokenCompleted

现在,我尝试在using System; using System.Collections.Generic; using System.Text; using System.Net; using Newtonsoft.Json; namespace Shadowsocks.Controller { class PanelAPI { private string baseURL = "https://test.com/api"; public event UploadStringCompletedEventHandler requestTokenCompleted; public event DownloadStringCompletedEventHandler requestServersCompleted; public void requestToken(string email, string passwd) { var logInfo = new { email = email, passwd = passwd }; WebClient client = new WebClient(); Uri uri = new Uri($"{baseURL}/token"); client.Headers[HttpRequestHeader.ContentType] = "application/json"; client.UploadStringCompleted += requestTokenCompleted; client.UploadStringAsync(uri, JsonConvert.SerializeObject(logInfo)); } } } 类中实现requestTokenCompleted。但是当我调用Authform时,requestTokenCompleted没有执行。我该如何解决?

api.requestToken()

1 个答案:

答案 0 :(得分:0)

您实际上并不是从requestTokenCompleted方法中触发requestToken()事件。

您需要:

if (requestTokenCompleted != null)
    requestTokenCompleted(this, new UploadStringCompletedEventArgs());

将其放置在您希望处理程序接收事件通知的方法中的任何位置。


编辑:很抱歉,要清楚,这里有两件事。

在此示例中,有两个不同的事件在起作用。第一个是在客户端上定义的事件。这是您无法控制的,在API代码中,您需要对其进行处理才能知道客户端何时完成。

第二个事件是您声明和控制的事件,它用于将其工作完成通知给下游客户(在本例中为AuthForm)。重要的是要了解此事件可以与基础WebClient事件具有相同的类型,但不一定如此。

因此,您将首先处理webclient事件。这是您可以执行此操作的一种方法:

    public void requestToken(string email, string passwd)
    {
        var logInfo = new { email = email, passwd = passwd };
        WebClient client = new WebClient();

        Uri uri = new Uri($"{baseURL}/token");

        client.Headers[HttpRequestHeader.ContentType] = "application/json";

        client.UploadStringCompleted += client_requestCompleted; // NOTE THE CHANGE
        client.UploadStringAsync(uri, JsonConvert.SerializeObject(logInfo));
    }

    private void client_requestCompleted(Object sender, UploadStringCompletedEventArgs e)
    {
        // Here is where you will want to chain out to your custom event.
        // In this example I simply pass the original completion event args
        if (requestTokenCompleted != null)
            requestTokenCompleted(this, e);
    }

请注意,我没有将原始事件连接到客户端的处理程序,而是像处理其他任何事件一样处理该事件。然后,我以连锁方式启动​​第二个事件。

要解决缺少公共构造函数的问题,在这里,我只是将我从客户端获得的构造函数传递给AuthForm的处理程序。但是由于我完全控制了事件,所以我可以改用完全不同的事件类型(将委托的签名更改为原始EventArgs或完全自定义的参数类型。

您需要选择最适合您的方法。我个人更希望更改参数类型,以使我的公共合同不会公开基于WebClient的实现细节,但是对您来说可能很好。