我试图了解WebClient.OpenRead
,WebClient.OpenReadAsync
和WebClient.OpenReadTaskAsync
之间的区别。
这些在阻塞线程方面似乎有所不同,但我不太了解。
您能解释这些差异吗?如果您能给我一些示例,那就太好了(示例不一定是示例代码,但是如果您能提供示例,那会很好)
答案 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
希望这会有所帮助。