使用哪个WebClient.OpenRead,OpenReadAsync或OpenReadTaskAsync

时间:2018-11-23 08:47:29

标签: c# webclient

我试图了解WebClient.OpenReadWebClient.OpenReadAsyncWebClient.OpenReadTaskAsync之间的区别。

这些在阻塞线程方面似乎有所不同,但我不太了解。
您能解释这些差异吗?如果您能给我一些示例,那就太好了(示例不一定是示例代码,但是如果您能提供示例,那会很好)

2 个答案:

答案 0 :(得分:1)

我建议WebClient现在或多或少已经过时,HttpClient更适合于任何面向.NET Framework 4.5+或.NET Core的对象。请注意,后者不会自动在HTTP错误代码(400+)上引发异常。

答案 1 :(得分:1)

正如您所说,区别在于线程阻塞行为。第一个(OpenRead())是线程阻塞操作,其他两个(不是)。例如,假设您到达 google.com 的网络延迟为300毫秒。当您执行const stackConfig: StackNavigatorConfig = { cardStyle: styles.card, navigationOptions: { headerBackTitleStyle: styles.headerBackTitle, headerStyle: styles.header, headerTintColor: "black" } }; const HomeStack = createStackNavigator( { HomeScreen, RestaurantDetailScreen, MenuScreen, ScannerScreen }, { ...stackConfig, initialRouteName: "HomeScreen", navigationOptions: ({ navigation }) => ({ headerLeft: parseFloat(navigation.state.key.slice(-1)) > 1 ? ( undefined ) : ( <Icon containerStyle={styles.leftIcon} type="ionicon" name={getIconName("menu")} onPress={navigation.toggleDrawer} /> ), ...stackConfig.navigationOptions }) } ); 时,您的应用程序在300毫秒内被“暂停” ,因此直到您的var stream = webClient.OpenRead(@"https://www.google.com");将流返回到webClient时,此行旁边的代码才会执行变量。这就是所谓的线程阻塞

当您在UI线程中执行此操作时(例如:在按钮单击处理程序中),您的应用程序将冻结并且不响应用户操作。这是不好的用户体验,因此永远不要在用户界面中调用线程阻塞内容。这是控制台应用程序的示例:

stream

第二种方法(OpenReadAsync())是异步的,并且在调用后立即不返回任何内容,因此不会阻塞您的线程。一段时间(300毫秒)后,您的var address = @"https://www.google.com/"; Console.WriteLine($"Opening stream from {address}"); using (var stream = webClient.OpenRead(address)) // this will block for 300ms { Console.WriteLine("Stream is open!"); // some other code } 将引发OpenReadCompleted事件,所有连接的侦听器将一一处理打开的流。这是一个示例:

webClient

最后一个(OpenReadTaskAsync())与TPL (Task Parallel Library)异步 / await 关键字有关。它在此方法返回的public partial class MainForm : Form { private WebClient _client = new WebClient(); public MainForm() { InitializeComponents(); _client.OpenReadCompleted += OpenReadCompletedHandler; } private void ButtonClickHandler(object sender, EventArgs e) { _client.OpenReadAsync(@"https://www.google.com/"); } private void OpenReadCompletedHandler(object sender, OpenReadCompletedEventArgs e) { // this event will be raiesed 300ms after 'Button' click var stream = e.Result; // <- here is your stream // some other code } } 中运行所有内容。这是一个示例:

Task

希望这会有所帮助。