Reputation: 6502
Still trying to wrap my head around async/await. I have the following method for drag/drop loading:
private async void p_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
List<string> CurvesToLoad = new List<string>();
List<string> TestsToLoad = new List<string>();
foreach (string file in files)
{
if (file.ToUpper().EndsWith(".CCC"))
CurvesToLoad.Add(file);
else if (file.ToUpper().EndsWith(".TTT"))
TestsToLoad.Add(file);
}
//SNIPPET IN BELOW SECTION
foreach (string CurvePath in CurvesToLoad)
{
Curve c = new Curve(CurvePath);
await Task.Run(() =>
{
c.load();
c.calculate();
});
AddCurveControls(c);
}
//END SNIPPET
foreach (string TestPath in TestsToLoad)
{
Test t = new Test(TestPath);
await Task.Run(() =>
{
t.load();
});
AddTestControls(t);
}
}
It is non-blocking as I expected - I am able to navigate between tabs of the TabControl as multiple items are loaded and I can see each tab pop up as it complete loading.
I then tried to convert to this:
private Task<Curve> LoadAndCalculateCurve(string path)
{
Curve c = new Curve(path);
c.load();
c.calculate();
return Task.FromResult(c);
}
And then replace the marked snippet from the first code block with:
foreach (string CurvePath in CurvesToLoad)
{
Curve c = await LoadAndCalculateCurve(CurvePath);
AddCurveControls(c);
}
And it becomes blocking - I can't navigate through tabs as it's loading, and then all of the loaded items appear at once when they are completed. Just trying to learn and understand the differences at play here - many thanks in advance.
EDIT:
Updated LoadAndCalculateCurve():
private async Task<Curve> LoadAndCalculateCurve(string path)
{
Curve c = new Curve(path);
await Task.Run(() => {
c.load();
c.calculate();
});
return c;
}
Upvotes: 1
Views: 114
Reputation: 203838
The implementation of your LoadAndCalculateCurve
method is to synchronously create a Curve
, synchronously load it and perform the calculation, and then return the result wrapped in a Task
. Nothing about this is asynchronously. When you await
it it will invoke the method, do all of the synchronous work to get the (already completed) task, and then add a continuation to that (already completed) task that will fire immediately.
When you instead use Task.Run
you're scheduling those long running operations to take place in another thread and immediately returning a (not yet completed) Task
that you can use to run code when it does eventually finish its work.
Upvotes: 0
Reputation: 171246
Async methods do not execute in a different thread, await
does not start a thread. async
merely enables the await
keyword and await
waits for something that already runs.
All of that code is running on the UI thread.
Upvotes: 2
Reputation: 302
So basically this is what is happening to my knowledge.
In your first code you write
foreach (string CurvePath in CurvesToLoad)
{
Curve c = new Curve(CurvePath);
await Task.Run(() =>
{
c.load();
c.calculate();
});
AddCurveControls(c);
}
this does the async flow as expected because you are using the Task.Run which adds the work to the ThreadPool queue.
In your second try you don't do this and you are using the same task. Try to use the same logic of (Task.Run) in the second try and I think it will work
Upvotes: 0