将回调值恢复到启动异步方法的函数的最佳方法



我是使用回调和异步函数的新手,所以我有点不确定解决这个问题的最佳方法。

我创建了一个名为 SendPhoto() 的函数,由我的 GUI 调用。 SendPhoto()函数与我的 GUI 位于不同的类中。

    public string SendPhoto(string filename)
    {
        byte[] response = PostFile(_url, filename);
        String responsestring = Encoding.ASCII.GetString(response);
        if (responsestring.StartsWith("ERROR:"))
            return responsestring;
        else if (responsestring.Contains("<valid>1</valid>"))
            return "OK";
        else
            return responsestring;
    }

我的PostFile()函数曾经调用WebClient.UploadFile(),并且响应返回到SendPhoto(),并且效果很好。 然后我决定要异步发送照片,因此在我的PostFile()函数中,我将调用从Uploadfile()更改为UploadFileAsync()

但是,我意识到UploadFileAsync()不返回值,并且我必须使用 UploadFileCompleteEventHandler 在完成上传时获取响应。 因此,我在与 SendPhoto()PostFile() 相同的类中编写了一个回调函数来检索响应,在该函数上实例化了一个 UploadFileCompletedEventHandler,并将其传递给我的 PostFile() 函数。

问题是我不确定如何将响应返回SendPhoto()函数,以便它可以解释响应并将友好的响应发送回 GUI。 以前,当一切都是同步的时,响应只是传递回堆栈,但现在,响应在几层之后返回。

现在PostFile()无法再将其返回给我,从回调函数向SendPhoto()返回响应的最佳方法是什么? 我想将事件处理程序回调移动到 GUI 并将UploadFileCompletedEventHandler传递给 SendPhoto() ,这又会将其发送到 PostFile() 。 但我试图将"业务逻辑"(即解释响应(排除在 GUI 类之外。

好的,今天早上做了更多的工作,并使用"await"找到了一个非常优雅的解决方案(谢谢,穆克塔迪尔·第纳尔! 我不得不更改对 UploadFileTaskAsync(( 的调用,以便它支持 "await" 关键字,我必须用"async"装饰我的所有方法并使它们返回任务,一直回到 GUI 的按钮单击事件处理程序,但是当我完成后,它工作得很好! 我相信这仅适用于.NET Framework 4.5。

    private async void UploadPhotoButton_Click(object sender, EventArgs e)
    {
        ...
        string theResult = await MyProvider.SendPhotoAsync(pathToFile, new UploadProgressChangedEventHandler(UploadProgressCallback));
        OutputBox.Text = theResult;
    }
    public async Task<string> SendPhotoAsync(string filename, UploadProgressChangedEventHandler changedHandler)
    {
        byte[] response = await PostFileAsync(_url, filename, changedHandler);
        String responsestring = Encoding.ASCII.GetString(response);
        if (responsestring.StartsWith("ERROR:"))
            return responsestring;
        else if (responsestring.Contains("<valid>1</valid>"))
            return "OK";
        else
            return responsestring;
    }
    async Task<byte[]> PostFileAsync(string uri, string filename, UploadProgressChangedEventHandler changedHandler)
    {
        byte[] response = null;
        using (WebClient client = new WebClient())
        {
            client.Headers = GetAuthenticationHeader();
            client.UploadProgressChanged += changedHandler;
            response = await client.UploadFileTaskAsync(new Uri(uri), filename);
        }
        return response;
    }

相关内容

  • 没有找到相关文章