关于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 }
在用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 }
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://github.com/neuecc/DynamicJson
作者:Simen.Net
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
浙公网安备 33010602011771号