最好的方法来获得回调值回启动异步方法的函数? [英] Best way to get callback value back to the function that initiated async method?

查看:165
本文介绍了最好的方法来获得回调值回启动异步方法的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是使用回调和异步函数的新手,所以我有点不确定最好的方法来处理这个。



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

  public string SendPhoto(string filename)
{
byte [] response = PostFile(_url,filename);

String responsestring = Encoding.ASCII.GetString(response);

if (onseestring.StartsWith(ERROR:))
return respondestring;
else if(responsestring.Contains(< valid> 1< / valid>))
returnOK;
else
return respondestring;
}

我的 PostFile()函数用于调用 WebClient.UploadFile(),并且响应返回到 SendPhoto()大。然后我决定要异步发送照片,因此在我的 PostFile()函数中,我更改了 Uploadfile() UploadFileAsync()<$ c> <$ c> 不返回值,我必须使用UploadFileCompletedEventHandler在上传完成后获取响应。因此,我在与 SendPhoto() PostFile()相同的类中写了一个回调函数来检索响应,在该函数上实例化了一个UploadFileCompletedEventHandler,并将其传递给我的 PostFile()函数。



问题是,不知道如何将响应返回到 SendPhoto()函数,以便它可以解释响应并将友好响应发送回GUI。以前,当一切都同步时,响应刚刚传递回堆栈,但现在,响应是后面几个层被删除。



什么是最好的方法从回调函数返回 SendPhoto(),现在 PostFile()不能再返回对我来说?我想到将事件处理程序回调移动到GUI,并将 UploadFileCompletedEventHandler 传递到 SendPhoto()发送到 PostFile()。但我想保持业务逻辑(即解释响应)从GUI类。

解决方案

在今天上午更多一些,并发现一个非常优雅的解决方案,使用await(感谢,Muctadir第纳尔!)。我不得不改变我的调用UploadFileTaskAsync(),为了支持await关键字,我不得不装饰我的所有方法与async,并使他们返回任务,一路返回到GUI的按钮点击事件处理程序,但是当我完成,它工作伟大!我相信这只会在.NET框架4.5中工作。

 私有异步void UploadPhotoButton_Click(object sender,EventArgs e)
{
...
string theResult = await MyProvider.SendPhotoAsync(pathToFile,new UploadProgressChangedEventHandler(UploadProgressCallback));
OutputBox.Text = theResult;
}

public async任务< string> SendPhotoAsync(string filename,UploadProgressChangedEventHandler changedHandler)
{
byte [] response = await PostFileAsync(_url,filename,changedHandler);

String responsestring = Encoding.ASCII.GetString(response);

if (onseestring.StartsWith(ERROR:))
return respondestring;
else if(responsestring.Contains(< valid> 1< / valid>))
returnOK;
else
return respondestring;
}

async任务< 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);
}

返回响应;
}


I'm new at using callbacks and async functions, so I'm a bit unsure of the best way to approach this.

I created a function called SendPhoto() that is called by my GUI. The SendPhoto() function is in a separate class from my 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;
    }

My PostFile() function used to call WebClient.UploadFile(), and the response was returned to SendPhoto(), and it worked great. Then I decided I wanted to send the photo asynchronously, so in my PostFile() function, I changed the call from Uploadfile() to UploadFileAsync().

However, I realized that UploadFileAsync() doesn't return a value, and I have to use a UploadFileCompletedEventHandler to get the response when it's done uploading. So, I wrote a callback function in the same class as SendPhoto() and PostFile() to retrieve the response, instantiated a UploadFileCompletedEventHandler on that function, and passed it into my PostFile() function.

The problem is that I'm not sure how the get the response back to the SendPhoto() function, so that it can interpret the response and send the friendly response back to the GUI. Before, when everything was synchronous, the response was just passed back up the stack, but now, the response is coming back a couple layers removed.

What is the best way to get the response back from the callback function to SendPhoto(), now that PostFile() can no longer return it to me? I thought of moving the event handler callback to the GUI and passing the UploadFileCompletedEventHandler to SendPhoto(), which would in turn send it to PostFile(). But I am trying to keep "business logic" (i.e. interpreting the response) out of the GUI class.

解决方案

Ok, worked on it some more this morning, and found a very elegant solution by using "await" (thanks, Muctadir Dinar!). I had to change my call to UploadFileTaskAsync(), in order for it to support the "await" keyword, and I had to decorate all of my methods with "async" and make them return task, all the way back to the GUI's button click event handler, but when I was done, it worked great! I believe this will only work in the .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;
    }

这篇关于最好的方法来获得回调值回启动异步方法的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆