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


расширяемость асинхронных функций



Download 6,27 Mb.
Pdf ko'rish
bet594/658
Sana12.06.2023
Hajmi6,27 Mb.
#950840
1   ...   590   591   592   593   594   595   596   597   ...   658
Bog'liq
CLR via C Programmirovanie na platforme Microsoft NET Framework 4 5 na yazyke C

расширяемость асинхронных функций
Что касается расширяемости, если в объект 
Task
можно упаковать операцию, 
которая завершится в будущем, то вы сможете использовать оператор 
await
для 
ожидания завершения этой операции. Представление всех разновидностей асин-
хронных операций одним типом (
Task
) чрезвычайно полезно, потому что оно 
позволяет реализовать комбинаторы (методы 
WhenAll
и 
WhenAny
класса 
Task
) и 
другие полезные операции. Позднее в этой главе данная возможность будет про-
демонстрирована на примере упаковки 
CancellationToken
с 
Task
, позволяющем 
использовать 
await
для асинхронной операции с поддержкой тайм-аута и отмены.
А сейчас я представлю еще один пример. Ниже приведен мой класс 
TaskLogger

который может использоваться для вывода информации о незавершенных асин-


800
Глава.28 .Асинхронные.операции.ввода-вывода
хронных операциях. Такая информация чрезвычайно полезна в ходе отладки, осо-
бенно если ваше приложение «виснет» из-за некорректного запроса или отсутствия 
реакции сервера.
public static class TaskLogger { 
public enum TaskLogLevel { None, Pending } 
public static TaskLogLevel LogLevel { get; set; } 
public sealed class TaskLogEntry { 
public Task Task { get; internal set; }
public String Tag { get; internal set; } 
public DateTime LogTime { get; internal set; } 
public String CallerMemberName { get; internal set; } 
public String CallerFilePath { get; internal set; }
public Int32 CallerLineNumber { get; internal set; }
public override string ToString() {
return String.Format("LogTime={0}, Tag={1}, Member={2}, File={3}({4})",
LogTime, Tag ?? "(none)", CallerMemberName, CallerFilePath, 
CallerLineNumber);
}
}
private static readonly ConcurrentDictionary s_log =
new ConcurrentDictionary();
public static IEnumerable GetLogEntries() { return s_log.Values; }
public static Task Log(this Task task, 
String tag = null, 
[CallerMemberName] String callerMemberName = null, 
[CallerFilePath] String callerFilePath = null, 
[CallerLineNumber] Int32 callerLineNumber = 1) { 
return (Task
Log((Task)task, tag, callerMemberName, callerFilePath, callerLineNumber); 
}
public static Task Log(this Task task, String tag = null, 
[CallerMemberName] String callerMemberName = null, 
[CallerFilePath] String callerFilePath = null, 
[CallerLineNumber] Int32 callerLineNumber = 1) { 
if (LogLevel == TaskLogLevel.None) return task
var logEntry = new TaskLogEntry { 
Task = task, 
LogTime = DateTime.Now, 
Tag = tag, 
CallerMemberName = callerMemberName, 
CallerFilePath = callerFilePath, 
CallerLineNumber = callerLineNumber 
}; 
s_log[task] = logEntry; 
task.ContinueWith(t => { TaskLogEntry entry; 
s_log.TryRemove(t, out entry); }, 
TaskContinuationOptions.ExecuteSynchronously); 
return task; 

}


801
Расширяемость.асинхронных.функций
Следующий фрагмент кода демонстрирует использование класса:
public static async Task Go() { 
#if DEBUG 
// Использование TaskLogger приводит к лишним затратам памяти
// и снижению производительности; включить для отладочной версии
TaskLogger.LogLevel = TaskLogger.TaskLogLevel.Pending; 
#endif 
// Запускаем 3 задачи; для тестирования TaskLogger их продолжительность
// задается явно.
var tasks = new List
Task.Delay(2000).Log("2s op"), 
Task.Delay(5000).Log("5s op"),
Task.Delay(6000).Log("6s op") 
}; 
try { 
// Ожидание всех задач с отменой через 3 секунды; только одна задача
// должна завершиться в указанное время.
// Примечание: WithCancellation - мой метод расширения,
// описанный позднее в этой главе.
await Task.WhenAll(tasks). 
WithCancellation(new CancellationTokenSource(3000).Token); 

catch (OperationCanceledException) { } 
// Запрос информации о незавершенных задачах и их сортировка
// по убыванию продолжительности ожидания
foreach (var op in TaskLogger.GetLogEntries().OrderBy(tle => tle.LogTime)) 
Console.WriteLine(op); 
}
Построив и запустив эту программу, я получаю следующий результат:
LogTime=7/16/2012 6:44:31 AM, Tag=6s op, Member=Go,
File=C:\CLR via C#\Code\Ch28 1 IOOps.cs(332) 
LogTime=7/16/2012 6:44:31 AM, Tag=5s op, Member=Go,
File=C:\CLR via C#\Code\Ch28 1 IOOps.cs(331)
Наряду с гибкостью, обусловленной использованием 
Task
, асинхронные функ-
ции предоставляют еще одну точку расширения: компилятор вызывает 
GetAwaiter
для операнда, использовавшегося с 
await
. Таким образом, операнд вообще не 
обязан быть объектом 
Task
; он может относиться к любому типу, содержащему 
метод 
GetAwaiter
. Пример моего собственного объекта ожидания, связывающего 
конечный автомат 
async
-метода с инициируемым событием.
public sealed class EventAwaiter : INotifyCompletion { 
private ConcurrentQueue m_events = new ConcurrentQueue(); 
private Action m_continuation; 
#region Члены, вызываемые конечным автоматом
// Конечный автомат сначала вызывает этот метод для получения
// объекта ожидания; возвращаем текущий объект
public EventAwaiter GetAwaiter() { return this; } 
продолжение



802
Download 6,27 Mb.

Do'stlaringiz bilan baham:
1   ...   590   591   592   593   594   595   596   597   ...   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