C# MongoDB无止境查找ToListSync

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

我试图从MongoDB集合中检索数据,但是发生了一些奇怪的事情。如果我显示一个MessageBox,则数据获取工作,如果我不显示,则不工作

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);
            }
        }
    }