C# Task若干问题浅析
场景:
分析数据库的表结构,并将表结构导出到word中。
方案1.直接用UI线程做,由于会造成UI卡顿,忽略。
方案2.用task:
Task ts = Task.Run(() => { for (int i = 0; i < listTables.Count; i++) { string name = listTables[i].Name; List<SqlserverTableStruct> list = form4DAL.GetTableStruct(name); this.Invoke(s, $"{i + 1}/{total}"); wordUtils.CreateWord(name, list); } });
ts.GetAwaiter().OnCompleted(() => { wordUtils.SaveFile("c:\\", filename + ".docx"); this.Invoke(s1, "生成完毕!"); });
方案3:与方案2类似,但最后部分使用:
ts.ContinueWith(t => { wordUtils.SaveFile("c:\\", filename + ".docx"); this.Invoke(s1, "生成完毕!"); });
代码分析:
方案2和方案3的类似的,但问题的关键在于用:OnCompleted和ContinueWith哪个更优?而为了回答这个问题,自己也进行了一些实验,最终发现了一些有意思的现象:
1.在.net framework框架下:OnCompleted和ContinueWith会随机出现其中一个先执行,而另一个后执行的情况。
2.在.net 8.0的环境下,始终是continuewith先执行,而complete后执行。
结论:
在新的框架下,这2个的逻辑是:task1执行后,然后判断是否有continue task,如果有则执行,如果没有则执行complete。而在老的.net framework框架下,感觉行为有所不同,甚至出现交替优先执行的情况。鉴于此,感觉在老的框架下,尽量避免两者同时使用(或许是bug).