如何向EventHandler传递参数?

5

不是那种基础问题。我正在开发一个应用程序,遇到这样的情况:文件将被下载,然后上传到FTP服务器,然后删除本地副本,最后在字典中为该文件名添加一个条目。因此,以下是代码:

public void download_This_WebPage(string url, string cookies_String, string local_Saving_File_Name_With_Path)
{
    WebClient wb = new WebClient();
    wb.Headers.Add(HttpRequestHeader.Cookie, cookies_String);
    // Below I want to pass this local_File _Path to the event handler
    wb.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wb,);
    wb.DownloadFileAsync(new Uri(url), local_Saving_File_Name_With_Path + ".html");
}

public void data_Download_Completed(Object sender, System.ComponentModel.AsyncCompletedEventArgs args)
{
      //use the file name to upload the file to FTP

}

public FTP_Completed
{
    // Delete the file
}

但是,我不知道如何将文件名传递给download_Completed事件处理程序。有人能指导我吗?

编辑: 感谢“Darin”和“Frederic”的答案。是否有一种通用的方式可以像下面这样将自定义数据传递给(已定义的)事件处理程序

void main_Fn()
{
    string my_Data = "Data";
    some_object a = new some_object();
    some_Object.click_event += new eventHandler(click_Happened);
    (Assume that the event passes two ints, I also want to pass the string "my_Data"
      to "click_Happened")
    some_object.start();
}

void click_Happened(int a, int b)
{
   // I want to get the string "my_Data" here. 
}

简而言之,如何欺骗签名?
2个回答

7
您可以将文件名传递给userToken参数以使用DownloadFileAsync()。操作完成后,它将在传递给data_Download_Completed()AsyncCompletedEventArgs参数的UserState属性中可用:
string filename = local_Saving_File_Name_With_Path + ".html";
wb.DownloadFileAsync(new Uri(url), filename, filename);

然后:

public void data_Download_Completed(Object sender,
    System.ComponentModel.AsyncCompletedEventArgs args)
{
    string filename = (string) args.UserState;
    // Now do something with 'filename'...
}

谢谢您提供的解决方案。但是,有没有办法将用户定义的数据注入到事件处理程序中? - prabhakaran
1
@prabhakaran,你可以在userToken中传递任何类型,包括任何classstruct的实例,并且它将在UserState中可用。 - Frédéric Hamidi
请原谅我的语法错误。我的意思是如何将此应用于任何事件处理程序? - prabhakaran
@prabhakaran,不,没有办法“欺骗签名”。如果处理程序委托需要两个int参数,则必须提供两个int参数,不能多也不能少。您可以尝试以另一种方式将my_Datasome_Object关联起来,例如使用与类本身关联的静态映射。 - Frédéric Hamidi

1

您可以使用 DownloadFileAsync 方法的第三个参数,该参数允许您将 UserState 传递给完成处理程序:

// subscribe to the completed event
wb.DownloadFileCompleted += data_Download_Completed;
string file = local_Saving_File_Name_With_Path + ".html";
wb.DownloadFileAsync(new Uri("url"), file, file);

在处理程序内部:

public void data_Download_Completed(Object sender, AsyncCompletedEventArgs args)
{
    // extract the filename from the UserState of the args
    string file = args.UserState as string;
    ...

}

我不知道谁先回答了这个问题。感谢您提供的解决方案。同样的问题问你。有没有办法将用户定义的数据注入到事件处理程序中? - prabhakaran
是的,可以使用UserState属性,就像我的答案中所示。您可以传递任意复杂的对象,而不仅仅是简单的字符串。 - Darin Dimitrov
请原谅我语法上的错误。我的意思是如何对任何事件处理程序执行此操作? - prabhakaran
我不明白你在问什么。 - Darin Dimitrov
我可以选择选中Frederic的答案吗?因为他的分数比你低很多。 - prabhakaran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接