【发布时间】:2014-10-19 23:21:45
【问题描述】:
我正在运行一个后台线程来从数据库中获取数据,这样当前线程(UI)就不会冻结。我正在使用 TPL 来实现这一点。
List<string> _myList1, _myList2;
private void LoadCollections(){
Task db_task = new Task(() => CallDB());
var continuations = db_task.ContinueWith((ant) =>
{
_myList1 = GetDataFromMetaData1();
_myList2 = GetDataFromMetaData2();
});
db_task.Start();
LoadTemplates(); //execute only after 'db_task' completes execution
}
在上面的代码中
CallDB() - 从数据库中获取数据并将其存储在元数据中。在这种情况下,将其视为字符串列表。 (比如List<string> MetaStrings)
GetDataFromMetaData1() 和 GetDataFromMetaData2() - 获取 2 个单独的列表,它们是 MetaStrings 的子列表。
现在我希望仅在 _myList1 和 _myList2 加载后执行函数 LoadTemplates,即当 db_task 完成执行时。目前,我正在使用这个
while(_mylist1==null && _mylist2==null)
Thread.Sleep(50);
LoadTemplates();
但这显然会在 UI 线程进入睡眠状态时冻结 UI。那么任何人都可以提出一种有效的方法来处理这种情况吗?
PS:LoadTemplates() 初始化了一些 ObservableCollection 变量。如果在子线程db_task 内调用LoadTemplates(),则会引发以下错误This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread。于是就出现了线程等待的场景。
【问题讨论】:
-
你不能使用异步和等待吗?
-
其实函数
LoadCollections是一个messenger事件。换句话说,当用户单击 UI 上的按钮时,ViewModel 会注册以调用LoadCollections。所以我有点迷失在这种情况下如何使用 async/await。 -
你不能使用Task.WaitAll(tasks);
-
不能用
await Task.Run()吗?
标签: c# multithreading