扩大
缩小

关于await任务执行顺序和Dynamic通过属性访问Json字符串

对于第一个问题主要是想验证在基于任务的异步模式 (TAP),await所等待的任务是在主线程执行下面的代码之后再来执行可等待的任务还是先执行可等待的任务再来执行主线程下的其他代码:

测试这个问题主要用如下调试代码

 1 static async Task Main(string[] args)
 2         {          
 3             var result=await TestTaskExcute();
 4             Console.WriteLine($"this is main thread {Thread.CurrentThread.ManagedThreadId}");
 5             Console.WriteLine($"this is a value:{result}");
 6             
 7         }
 8 
 9         private static async Task<int> TestTaskExcute()
10         {
11             var results=1;
12             var tasksArray=new Task[4];           
13             //test action delegate
14             await Task.Run(()=>{
15                     Task.Delay(10000);               
16                     Console.WriteLine($"this is action task internal thread {Thread.CurrentThread.ManagedThreadId}");
17                 });
18             for(var i=0;i<4;i++)
19             {
20                 var a=i;
21                 tasksArray[a] =Task.Run(()=>{             
22                     Console.WriteLine($"this is action task internal thread {Thread.CurrentThread.ManagedThreadId}.this is {a} cycle");
23                     return ++results;
24                 });
25             }
26             //test fun delegate
27             // a= await Task.Run(()=>{
28             //     Task.Delay(10000);               
29             //     Console.WriteLine($"this is fun task internal thread {Thread.CurrentThread.ManagedThreadId}");
30             //     return a;
31             // });
32             
33             //Task.WaitAll();
34             Task.WaitAll(tasksArray);
35 
36             //await Task.WhenAll(tasksArray);
37             Console.WriteLine($"this is task await thread {Thread.CurrentThread.ManagedThreadId}");
38             return 1;
39         }      
测试await的执行顺序

在用Task.WaitAll()不传入等待的任务的执行结果,如下图:

 

 在用Task.WaitAll(taskArray)出入等待的任务的执行结果,如下图:

综合比较上两张图其实Task.WaitAll()在你没传入TaskArray时相当于一行无效的代码,任务在没有await等待返回时程序继续往下执行,直到方法执行完返回值时再来调用Task任务。

当你有等待await时会立即执行任务返回任务执行的结果。

 主要参考:

https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/async/

 

对于下面代码

var jsonString='{"foo":"json", "bar":100, "nest":{ "foobar":true }}';

var jsonObj = JSON.parse(jsonString);

jsonObj.foo

jsonObj.nest.foobar

熟悉js的 在这里jsonObj是一个动态类型。在C#中有没有办法和js一样,反序列化一个dynamic类型来方便的访问Json数据?

在下面代码中主要是通过继承DynamicObject重写TryGetMember方法来实现C#像js那样访问

实现代码如下:

 public class DynamicJson:DynamicObject
    {
        #region private variable

        //represents xml element
        private readonly XElement xml;

        //defind the type of element value 
        private readonly JsonType jsonType;
        private enum JsonType
        {
            @string,number,boolean,@object,array,@null
        }

        #endregion

        #region private method

        /// <summary>
        /// Create a new attribute for xelement and get the value
        /// </summary>
        /// <param name="type">jsontype</param>
        /// <returns>new attribute</returns>
        private static XAttribute CreateTypeAttr(JsonType type)
        {
            return new XAttribute("type",type.ToString());
        }

        /// <summary>
        /// Private constructor can only be called internally
        /// </summary>
        /// <param name="element"></param>
        /// <param name="type"></param>
        private DynamicJson(XElement element,JsonType type)
        {
            Debug.Assert(type==JsonType.array||type==JsonType.@object);
            xml=element;
            jsonType=type;
        }
        #endregion

        #region public method
        public DynamicJson()
        {
            xml=new XElement("root",CreateTypeAttr(JsonType.@object));
            jsonType=JsonType.@object;
        }

        /// <summary>
        /// Read json string and convert to xelement
        /// </summary>
        /// <param name="json"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static dynamic Parse(string json,Encoding encoding)
        {
            using(var jsonReader=JsonReaderWriterFactory.CreateJsonReader(encoding.GetBytes(json),XmlDictionaryReaderQuotas.Max))
            {
                return ToValue(XElement.Load(jsonReader));
            }
        }

        /// <summary>
        /// According to Jsontype return element value
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public static dynamic ToValue(XElement element)
        {
            var type=(JsonType)Enum.Parse(typeof(JsonType),element.Attribute("type").Value);
            switch(type)
            {
                case JsonType.boolean:
                    return (bool)element;
                case JsonType.number:
                    return (double)element;
                case JsonType.@string:
                    return (string)element;
                case JsonType.@object:
                case JsonType.array:
                    return new DynamicJson(element,type);
                case JsonType.@null:
                default:
                    return null;
            }
        }

        /// <summary>
        /// According the binder name find value
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var element=xml.Element(binder.Name);
            if(element==null)
            {
                result=null;
                return false;
            }
            result=ToValue(element);
            return true;
        }
        #endregion
    }
DynamicJson
 var jsonStr=@"{""foo"":""json"", ""bar"":100, ""nest"":{ ""foobar"":true } }";
            var jsonObj = DynamicJson.Parse(jsonStr,Encoding.Unicode);
            Console.WriteLine(jsonObj.foo);
            Console.WriteLine(jsonObj.bar);
            Console.WriteLine(jsonObj.nest.foobar);

  输出结果为:

主要参考:

https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/types/walkthrough-creating-and-using-dynamic-objects

https://github.com/neuecc/DynamicJson

 

posted @ 2018-03-15 11:58  Simen.Net  阅读(480)  评论(0)    收藏  举报