【发布时间】:2017-07-07 04:31:33
【问题描述】:
如果有这个代码:
Task[] tasks = new Task[3];
int index = 0;
foreach (KeyValuePair<string, int> packageId in PackageIds)
{
await Task.Run(() => _logger.Log(packageId.Key));
tasks[index] = Task.Factory.StartNew(() =>
{
Log(packageId.Key);
});
index++;
}
Task.WaitAll(tasks);
_logger.Log("all done");
这是日志函数:
private void Log(string message)
{
ListViewItem lv = new ListViewItem
{
Text = $"{DateTime.Now:dd-MM-yyyy hh:mm:ss}"
};
lv.SubItems.Add(message);
if (listView1.InvokeRequired)
Invoke(new Action(() => Log(message)));
else
listView1.Items.Add(lv);
}
当我运行它时,我可以看到代码尝试调用 listView1。但在那之后,应用程序挂起并且根本不继续。当我删除 Log() 并再次运行它时,它可以完美运行。
如何使用日志记录运行此代码?
【问题讨论】:
-
你显然有无限循环/递归 -
Log函数将永远调用自己,以防listView1.InvokeRequired = true -
如何使用日志运行此代码? - 您试图通过从另一个线程记录消息来实现什么?为什么不在 await 之后在
foreach循环内的 listview 中简单地添加日志消息? -
正如现在的代码一样,绝对没有理由使用任务。一切仍然在 UI 线程上完成。
-
如果没有好的minimal reproducible example,就不可能知道如何最好地处理您的方案。也就是说,您发布的代码是各种错误的。最大的问题(最有可能导致挂起)是您调用
Task.WaitAll(),而(显然)在其他线程中执行的代码最终将要调用Control.Invoke()并使用您正在阻塞的线程。除此之外,根本不清楚你为什么要打扰Task的东西。它似乎没有任何好处,只会让你感到困惑。
标签: c# winforms asynchronous task