Как вы сказали, разница заключается в поведении блокировки потоков.Первый ( OpenRead () ) - операция блокировки потоков, два других - нет.Например, предположим, что латентность вашей сети для достижения google.com составляет 300 мс.Когда вы делаете var stream = webClient.OpenRead(@"https://www.google.com");
, ваше приложение "ставится на паузу" на эти 300 мс, поэтому код рядом с этой строкой не будет выполняться, пока ваш webClient
не вернет поток в переменную stream
.Это вызывает Блокировка потока .
Когда вы делаете это в UI-потоке (например: в обработчике нажатия кнопки) - ваше приложение зависает и не реагирует на действия пользователя.Это плохо пользовательский опыт, поэтому никогда не вызывайте блокировку потоков в вашем интерфейсе.Вот пример для консольного приложения:
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
}
Второй метод ( OpenReadAsync () ) равен асинхронно и не возвращает ничего сразу после вызова, поэтому ваш поток незаблокирован.Через некоторое время (300 мс) webClient
будет вызвано событие OpenReadCompleted , и все подключенные слушатели будут обрабатывать открытый поток один за другим.Вот пример:
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
}
}
Последний ( OpenReadTaskAsync () ) полностью о TPL (Task Parallel Library) и async / ждут ключевых слов.Он запускает все вещи в Task
, который возвращается этим методом.Вот пример:
public partial class MainForm : Form
{
private WebClient _client = new WebClient();
public MainForm()
{
InitializeComponents();
}
private async void ButtonClickHandler(object sender, EventArgs e)
{
// after 'await' keyword, execution will be returned from this method immediately
// meanwhile, actual acquiring of 'stream' is running in a background thread
using (var stream = await _client.OpenReadTaskAsync(@"https://www.google.com/"))
{
// after 300ms, this code will be continued in UI thread
// result will be automaticly unpacked to 'stream' variable
// some other code
}
}
}
Надеюсь, это поможет.