C# MongoDB无止境查找ToListSync
我试图从MongoDB集合中检索数据,但是发生了一些奇怪的事情。如果我显示一个MessageBox,则数据获取工作,如果我不显示,则不工作C# MongoDB无止境查找ToListSync,c#,winforms,mongodb,asynchronous,async-await,C#,Winforms,Mongodb,Asynchronous,Async Await,我试图从MongoDB集合中检索数据,但是发生了一些奇怪的事情。如果我显示一个MessageBox,则数据获取工作,如果我不显示,则不工作 static class MongoDBController { static MongoClient client = new MongoClient("mongodb://localhost"); public static async Task<List<Course>> GetCourses(string d
static class MongoDBController {
static MongoClient client = new MongoClient("mongodb://localhost");
public static async Task<List<Course>> GetCourses(string dbName = "school") {
// Get our course collection
var db = client.GetDatabase(dbName);
var collection = db.GetCollection<Course>("courses");
// Create an empty filter
var filter = new BsonDocument();
// Use the empty filter to get all courses from the database
return await collection.Find(filter).ToListAsync();
}
}
现在,如果我删除抓取工作(耶!)弹出窗口,我的列表框将永远不会被填满
我做错了什么?正如Alex善意地指出的那样,问题的解决方案是使
FillCourseList也异步化。这允许程序在从数据库获取数据时继续运行。我之前接到的阻拦电话显然是问题的原因。不过,这确实增加了对Windows窗体的需求
private delegate void SetListCallback(List<Course> result);
private async Task GetCourseList() {
Task<List<Course>> courseTask = MongoDBController.GetCourses();
List<Course> result = await courseTask.ConfigureAwait(false);
// When finished, fill the listbox
FillCourseList(result);
}
private void FillCourseList(List<Course> result) {
// If the calling thread's ID doesn't match the creating thread's ID
// Invoke this method on the correct thread via the delegate
if (this.listBox_overview_vakken.InvokeRequired) {
SetListCallback d = new SetListCallback(FillCourseList);
this.Invoke(d, result);
} else {
foreach (Course s in result) {
listBox_overview_vakken.Items.Add(s);
}
}
}
private delegate void SetListCallback(列表结果);
私有异步任务GetCourseList(){
任务courseTask=MongoDBController.GetCourses();
列表结果=等待课程任务。配置等待(false);
//完成后,填写列表框
FillCourseList(结果);
}
私有void FillCourseList(列表结果){
//如果调用线程的ID与创建线程的ID不匹配
//通过委托在正确的线程上调用此方法
if(此.listBox\u概述\u vakken.invokererequired){
SetListCallback d=新的SetListCallback(FillCourseList);
调用(d,结果);
}否则{
foreach(课程结果){
列表框\u概述\u vakken.Items.Add;
}
}
}
我不确定是什么导致了这种行为(SynchronizationContext中的一些棘手的事情?),但我建议您阅读。此courseTask.Result
是一个阻塞调用,以利用async
,您可能需要将FillCourseList
更改为private async Task FillCourseList
,然后执行。。。结果=等待课程任务。配置等待(false)
您还应该“冒泡”调用堆栈中方法的async/Wait
签名。@Alex,感谢您在这方面的输入,允许我修复我的问题。一个好的答案,包括封送回UI线程async void
仅适用于顶级事件处理程序。改用异步任务
private delegate void SetListCallback(List<Course> result);
private async Task GetCourseList() {
Task<List<Course>> courseTask = MongoDBController.GetCourses();
List<Course> result = await courseTask.ConfigureAwait(false);
// When finished, fill the listbox
FillCourseList(result);
}
private void FillCourseList(List<Course> result) {
// If the calling thread's ID doesn't match the creating thread's ID
// Invoke this method on the correct thread via the delegate
if (this.listBox_overview_vakken.InvokeRequired) {
SetListCallback d = new SetListCallback(FillCourseList);
this.Invoke(d, result);
} else {
foreach (Course s in result) {
listBox_overview_vakken.Items.Add(s);
}
}
}