zoukankan      html  css  js  c++  java
  • 随笔,再聊异步函数机制

    1,异步函数做了以下事情.

    • 创建一个状态机对象
    • 创建一个m_builder对象---一个TaskCompleteSource<TResult>对象,类似的.

    • 返回该对象的Task
    • 状态机在 await 操作符上面,做了以下几件事情
    1.                  调用GetAwaiter()函数来获取一个TaskAwaiter对象:
    2.                  如果其状态是Iscompleted,则进行进行GetResult获取异步函数结果,如果是没完成状态,则给其添加一个回调函数
    3.                  当异步任务完成后,引用该异步任务的ContinueWith来调用状态机的MoveNext()函数.
    4.                  在返回状态机的第一步,状态机调用GetResult函数来获取awaiter的结果.(如果异步函数出错的话,会报错.)
    5.                  当函数有错的时候,就设定SetException(exception),没错的时候,就设定SetResult(result).

    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:UsersusernameDocumentsVisual Studio 2012ProjectsCallerInfoCSCallerInfoCSForm1.cs
    //  source line number: 31
  • 相关阅读:
    python高阶函数filter
    python的生成器与yield
    python返回多个参数
    第一冲刺阶段工作总结09
    第一冲刺阶段工作总结08
    第一冲刺阶段工作总结07
    第一冲刺阶段工作总结06
    第八周学习进度表
    微软拼音简捷关于人机交互设计的相关评价
    第一冲刺阶段工作总结05
  • 原文地址:https://www.cnblogs.com/frogkiller/p/12527595.html
Copyright © 2011-2022 走看看