Net framework 5, а также среды Visual Studio 2012 и C#



Download 6,27 Mb.
Pdf ko'rish
bet603/658
Sana12.06.2023
Hajmi6,27 Mb.
#950840
1   ...   599   600   601   602   603   604   605   606   ...   658
Bog'liq
CLR via C Programmirovanie na platforme Microsoft NET Framework 4 5 na yazyke C


Глава.28 .Асинхронные.операции.ввода-вывода
интерфейса. Для приложений ASP.NET код, следующий за оператором 
await
, за-
ведомо выполняется в пуле потока, с которым связаны региональные стандарты 
и идентификационные данные клиента.
В большинстве случаев возобновление работы конечного автомата с использо-
ванием потоковой модели приложения чрезвычайно полезно и удобно. Впрочем, 
в отдельных случаях оно способно создать проблемы. Следующий пример вызывает 
взаимную блокировку приложения WPF:
private sealed class MyWpfWindow : Window { 
public MyWpfWindow() { Title = "WPF Window"; } 
protected override void OnActivated(EventArgs e) { 
// Запрос свойства Result не позволяет GUI-потоку вернуть управление; 
// поток блокируется в ожидании результата
String http = GetHttp().Result; // Синхронное получение строки
base.OnActivated(e); 

private async Task GetHttp() { 
// Выдача запроса HTTP и возврат из GetHttp 
HttpResponseMessage msg = await new 
HttpClient().GetAsync("http://Wintellect.com/"); 
// В эту точку мы никогда не попадем: GUI-поток ожидает завершения
// этого метода, а метод не может завершиться, потому что GUI-поток
// ожидает его завершения > ВЗАИМНАЯ БЛОКИРОВКА! 
return await msg.Content.ReadAsStringAsync(); 

}
Разработчики, создающие библиотеки классов, определенно должны знать о клас-
се 
SynchronizationContext
. Это позволит им создавать высокопроизводительный 
код, работающий со всеми моделями приложений. Так как большая часть библио-
течного кода не зависит от модели приложения, нам хотелось бы избежать допол-
нительных затрат, связанных с использованием объекта 
SynchronizationContext

Кроме того, разработчики библиотек классов должны сделать все возможное, чтобы 
помочь разработчикам приложений избежать ситуаций взаимной блокировки. 
Для решения обеих проблем классы 
Task
и 
Task
предоставляют метод 
ConfigureAwait
с сигнатурой следующего вида:
// Task определяет метод: 
public ConfiguredTaskAwaitable 
ConfigureAwait(Boolean continueOnCapturedContext); 
// Task определяет метод: 
public ConfiguredTaskAwaitable 
ConfigureAwait(Boolean continueOnCapturedContext); 
При передаче 
true
метод ведет себя так, как если бы он вообще не вызвал-
ся. Но если передать значение 
false
, то оператор 
await
не запрашивает объект 


813
Асинхронная.реализация.сервера
SynchronizationContext
вызывающего потока, а когда поток пула завершает за-
дание 
Task
, то происходит простое завершение с выполнением кода после оператора 
await
через поток пула.
Хотя мой метод 
GetHttp
не входит в библиотеку классов, проблема взаимной 
блокировки исчезает при добавлении вызовов 
ConfigureAwait
. Измененная версия 
метода 
GetHttp
выглядит так:
private async Task GetHttp() { 
// Выдача запроса HTTP и возврат из GetHttp
HttpResponseMessage msg = await new 
HttpClient().GetAsync("http://Wintellect.com/") 
.ConfigureAwait(false); 
// На этот раз управление попадет в эту точку, потому что поток пула
// может выполнить этот код (в отличие от выполнения через GUI-поток).
return await msg.Content.ReadAsStringAsync().ConfigureAwait(false); 
}
Как показывает предыдущий код, вызов 
ConfigureAwait(false)
должен быть 
применен к каждому объекту 
Task
, используемому с 
await
. Это связано с тем, что 
асинхронные операции могут завершаться синхронно, и когда это происходит, вы-
зывающий поток просто продолжает выполняться без возвращения управления 
стороне вызова; вы никогда не знаете, какой операции потребуется игнорировать 
объект 
SynchronizationContext
, поэтому необходимо приказать всем операциям 
игнорировать его. Это также означает, что код библиотеки классов должен быть 
независимым от модели приложения.
Также можно переписать метод 
GetHttp
так, как показано ниже, чтобы все вы-
полнение происходило через поток пула:
private Task GetHttp() { 
return Task.Run(async () => { 
// Выполнение в потоке пула, с которым не связан
// объект SynchronizationContext
HttpResponseMessage msg = await new 
HttpClient().GetAsync("http://Wintellect.com/"); 
return await msg.Content.ReadAsStringAsync(); 
}); 
}
Обратите внимание: в этой версии кода метод 
GetHttp
не является асинхронной 
функцией; я удалил ключевое слово 
async
из сигнатуры метода, потому что метод 
более не содержит оператор 
await
. С другой стороны, лямбда-выражение, пере-
даваемое 
Task.Run
, является асинхронной функцией.

Download 6,27 Mb.

Do'stlaringiz bilan baham:
1   ...   599   600   601   602   603   604   605   606   ...   658




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish