Reputation: 683
I'm attempting to retrieve data from a MongoDB collection, however something strange is happening. If I show a MessageBox the data fetch works, if I don't it doesn't.
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();
}
}
The code above gets the content out of the database, the code below - found in my Form1.cs
- places it inside a ListBox.
private void FillCourseList() {
Task<List<Course>> courseTask = MongoDBController.GetCourses();
MessageBox.Show("Fetching worked (yay!)");
// get the result
List<Course> result = courseTask.Result;
// Show every course found in the resultset
foreach (Course s in result) {
listBox_overview_vakken.Items.Add(s);
}
}
Now if I remove the Fetching worked (yay!) pop-up my listBox never gets filled.
What am I doing wrong?
Upvotes: 3
Views: 3055
Reputation: 683
The solution to the issue, as Alex kindly pointed out, is making the FillCourseList
asynchronous aswell. This allows the program to continue running while the data is fetched from the database. The blocking call I had before apparently was the cause of the issue. This does add the need for thread-safe calls to the Windows Form though.
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);
}
}
}
Upvotes: 3