C# 如何等待webclient OpenReadAsync完成
我正在使用WebClient在Windows Phone 8.1应用程序中从internet下载一些东西。 下面是我在我的应用程序中使用的示例代码——我调用了下面的方法,但我的webclient并没有等待完成读取操作并在OpenReadAsync调用后立即返回 如何确保方法返回操作必须等到OpenReadCompleted事件完成? 我见过多个类似的问题,但找不到解决方案C# 如何等待webclient OpenReadAsync完成,c#,windows-phone-8.1,async-await,task-parallel-library,webclient,C#,Windows Phone 8.1,Async Await,Task Parallel Library,Webclient,我正在使用WebClient在Windows Phone 8.1应用程序中从internet下载一些东西。 下面是我在我的应用程序中使用的示例代码——我调用了下面的方法,但我的webclient并没有等待完成读取操作并在OpenReadAsync调用后立即返回 如何确保方法返回操作必须等到OpenReadCompleted事件完成? 我见过多个类似的问题,但找不到解决方案 MyCustomObject externalObj; // my custom object private stat
MyCustomObject externalObj; // my custom object
private static void CheckNetworkFile()
{
try
{
WebClient webClient = new WebClient();
webClient.OpenReadCompleted += (s, e) =>
{
externalObj = myReadWebclientResponse(e.Result); // my custom method to read the response
};
webClient.OpenReadAsync(new Uri("http://externalURl.com/sample.xml", UriKind.Absolute));
}
catch (Exception)
{
externalObj = null;
}
}
我建议您使用.NET4.5中引入的关键字组合。您需要将async
关键字添加到方法中,使其返回任务
,建议使用async
后缀结束方法:
MyCustomObject externalObj;
private static async Task CheckNetworkFileAsync()
{
try
{
WebClient webClient = new WebClient();
Stream stream = await webClient.OpenReadTaskAsync(new Uri("http://externalURl.com/sample.xml", UriKind.Absolute));
externalObj = myReadWebclientResponse(stream);
}
catch (Exception)
{
externalObj = null;
}
}
编辑:
正如您所说,WebClient.OpenReadTaskAsync
不适用于WP8.1,因此让我们创建一个扩展方法,以便:
public static class WebClientExtensions
{
public static Task<Stream> OpenReadTaskAsync(this WebClient client, Uri uri)
{
var tcs = new TaskCompletionSource<Stream>();
OpenReadCompletedEventHandler openReadEventHandler = null;
openReadEventHandler = (sender, args) =>
{
try
{
tcs.SetResult(args.Result);
}
catch (Exception e)
{
tcs.SetException(e);
}
};
client.OpenReadCompleted += openReadEventHandler;
client.OpenReadAsync(uri);
return tcs.Task;
}
}
公共静态类WebClientTextensions
{
公共静态任务OpenReadTaskAsync(此WebClient客户端,Uri)
{
var tcs=new TaskCompletionSource();
OpenReadCompletedEventHandler openReadEventHandler=null;
openReadEventHandler=(发送方,参数)=>
{
尝试
{
tcs.SetResult(args.Result);
}
捕获(例外e)
{
tcs.SetException(e);
}
};
client.OpenReadCompleted+=openReadEventHandler;
OpenReadAsync(uri);
返回tcs.Task;
}
}
现在您可以在网络客户端上使用它了
您可以在中找到很好的阅读材料,只需在搜索栏中按该标记进行筛选。我希望这不是太离题,但其他正在研究这一点的人可能想知道,上面的代码示例也可以用于Silverlight中的WCF调用。请确保首先添加Microsoft.Bcl.Async NuGet包。以下是一个WCF代码示例:
public static async Task<string> AuthenticateAsync(string userName, string password)
{
var dataAccessServiceClient = new DataAccessServiceClient("DataAccessService");
var taskCompletionSource = new TaskCompletionSource<string>();
EventHandler<AuthenticateCompletedEventArgs> completedHandler = null;
completedHandler = (s, args) =>
{
try
{
taskCompletionSource.SetResult(args.Result);
}
catch (Exception e)
{
taskCompletionSource.SetException(e);
}
};
dataAccessServiceClient.AuthenticateCompleted += completedHandler;
dataAccessServiceClient.AuthenticateAsync(userName, password);
return await taskCompletionSource.Task;
}
使方法异步
。如果您不知道这意味着什么,请阅读C#中的async
方法。感谢@Alxandr的回复,我确实尝试过使用async/wait,但行为相同。OpenReadCompleted事件在方法返回调用后完成。感谢您的回复,实际上此OpenReadTaskAsync()不在WindowsPhone平台中。Salam,我认为您必须将“taskComplete”更改为“tcs.SetResult(…)”@SayedBolfazlfatemi感谢您让我知道。编辑了我的答案。谢谢你的扩展提示。哦,我的上帝!!!这是我见过的Silverlight最重要的代码示例。这不仅适用于REST调用,也适用于WCF调用。到目前为止,我一直在使用没有async/await操作符的旧异步模型来调用WCF/REST方法。我们的代码到处都是可怕的事件处理程序,代码就像一个迷宫。这将极大地清理我们的代码。但是我应该提到,为了使用它,我们必须添加Microsoft.Bcl.Async NuGet包。这是解开这个问题的另一把钥匙。
var result = await AuthenticateAsync(username, password);