仍然试图绕过async / await。我有以下拖放加载方法:
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);
}
}
正如我所料,它是非阻塞的 - 我可以在TabControl的选项卡之间导航,因为加载了多个项目,我可以看到每个选项卡在完成加载时弹出。
然后我尝试转换为:
private Task<Curve> LoadAndCalculateCurve(string path)
{
Curve c = new Curve(path);
c.load();
c.calculate();
return Task.FromResult(c);
}
然后用以下代码替换第一个代码块中标记的代码段:
foreach (string CurvePath in CurvesToLoad)
{
Curve c = await LoadAndCalculateCurve(CurvePath);
AddCurveControls(c);
}
它变得阻塞 - 我无法在加载时浏览标签,然后在完成后立即显示所有加载的项目。只是试着学习和理解这里的差异 - 非常感谢提前。
编辑:
更新了LoadAndCalculateCurve():
private async Task<Curve> LoadAndCalculateCurve(string path)
{
Curve c = new Curve(path);
await Task.Run(() => {
c.load();
c.calculate();
});
return c;
}
答案 0 :(得分:2)
异步方法不在另一个线程中执行,await
不会启动线程。 async
仅启用await
关键字,await
等待已经运行的内容。
所有代码都在UI线程上运行。
答案 1 :(得分:0)
所以基本上这就是我所知道的。
在您编写的第一个代码中
foreach (string CurvePath in CurvesToLoad)
{
Curve c = new Curve(CurvePath);
await Task.Run(() =>
{
c.load();
c.calculate();
});
AddCurveControls(c);
}
这会像预期的那样执行异步流,因为您正在使用Task.Run,它将工作添加到ThreadPool队列。
在第二次尝试中,您不会这样做而且您正在使用相同的任务。尝试在第二次尝试中使用相同的(Task.Run)逻辑,我认为它将起作用
答案 2 :(得分:0)
LoadAndCalculateCurve
方法的实现是同步创建Curve
,同步加载并执行计算,然后返回包含在Task
中的结果。没有任何关于这是异步的。当你await
它将调用该方法时,执行所有同步工作以获得(已完成的)任务,然后为将立即触发的那个(已完成的)任务添加一个继续。
当您改为使用Task.Run
时,您会将这些长时间运行的操作安排在另一个线程中,而立即返回一个(尚未完成的)Task
您可以用于在最终完成工作时运行代码。