1,异步函数做了以下事情.
2,结论:
1,如果异步函数使用嵌套:那么 所有在await之前的代码都是同步完成的,task1-->task2--->task3...然后await后面的代码是异步完成的,但是对于task1,来说,是 task3---完成了---task2----完成了---task1---完成了.
2,异步函数终结一般来说是使用
public static async Task WithCancellation(this Task originalTask, CancellationToken ct) { var cancelTask = new TaskCompletionSource<Void>(); using (ct.Register( t => ((TaskCompletionSource<Void>)t).TrySetResult(new Void()), cancelTask)) { Task any = await Task.WhenAny(originalTask, cancelTask.Task); if (any == cancelTask.Task) ct.ThrowIfCancellationRequested(); } await originalTask; }
3,TaskLogger类
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<Task, TaskLogEntry> s_log = new ConcurrentDictionary<Task, TaskLogEntry>(); public static IEnumerable<TaskLogEntry> GetLogEntries() { return s_log.Values; } public static Task<TResult> Log<TResult>(this Task<TResult> task, String tag = null, [CallerMemberName] String callerMemberName = null, [CallerFilePath] String callerFilePath = null, [CallerLineNumber] Int32 callerLineNumber = -1) { return (Task<TResult>) 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, CallerFilePath = callerFilePath, CallerLineNumber = callerLineNumber, CallerMemberName = callerMemberName }; s_log[task] = logEntry; task.ContinueWith(t => { TaskLogEntry entry; s_log.TryRemove(t, out entry); }, TaskContinuationOptions.ExecuteSynchronously); return task; } }
特别注意三个Caller特性,表明将获取Caller的属性.
public void DoProcessing() { TraceMessage("Something happened."); } public void TraceMessage(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0) { System.Diagnostics.Trace.WriteLine("message: " + message); System.Diagnostics.Trace.WriteLine("member name: " + memberName); System.Diagnostics.Trace.WriteLine("source file path: " + sourceFilePath); System.Diagnostics.Trace.WriteLine("source line number: " + sourceLineNumber); } // Sample Output: // message: Something happened. // member name: DoProcessing // source file path: c:\Users\username\Documents\Visual Studio 2012\Projects\CallerInfoCS\CallerInfoCS\Form1.cs // source line number: 31
原文:https://www.cnblogs.com/frogkiller/p/12527595.html