我是使用回调和异步函数的新手,所以我有点不确定最好的解决方法。
我创建了一个名为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()
没有返回值,我必须使用UploadFileCompletedEventHandler来完成上传时的响应。所以,我在与SendPhoto()
和PostFile()
相同的类中编写了一个回调函数来检索响应,在该函数上实例化一个UploadFileCompletedEventHandler,并将其传递给我的PostFile()
函数。
问题在于我不确定如何将响应返回到SendPhoto()
函数,以便它可以解释响应并将友好响应发送回GUI。之前,当一切都是同步时,响应刚刚传回堆栈,但现在,响应又回来了几层。
现在SendPhoto()
无法再将回复函数发回给我,从回调函数回复到PostFile()
的最佳方式是什么?我想过将事件处理程序回调移动到GUI并将UploadFileCompletedEventHandler
传递给SendPhoto()
,然后PostFile()
将其发送到{{1}}。但我试图将“业务逻辑”(即解释响应)保留在GUI类之外。
答案 0 :(得分:1)
好的,今天早上又做了一些工作,并通过使用“await”找到了一个非常优雅的解决方案(谢谢,Muctadir Dinar!)。我不得不改变对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;
}