【发布时间】:2017-08-12 01:43:16
【问题描述】:
当我调用 BuildCustomer.StartTask 时,我会调用一个方法 WriteToDatabase。在 WriteToDatabase 中,我想将状态发送回 MainForm 以将状态写入 GUI。当代码达到那个点时,我的应用程序会冻结并且没有错误。我确实发现如果我删除 task.Wait(),它会停止冻结并工作。但我想我想要等待,因为我的 BuildCustomer 需要一些时间并将大量更新(包括来自 Common 类的更多更新)写入 GUI。有人可以告诉我哪里出了问题或者我应该做些什么不同的事情吗?这是一个 .Net 4 项目,所以我不能使用异步,我已经看到了其他答案。
public partial class MainForm : Window
{
public MainForm()
{
Common.SendMessage += UpdateStatus;
}
private void Button_Click(object sender, EventArgs e)
{
BuildCustomer.StartTask();
}
private void UpdateStatus(string message)
{
Dispatcher.Invoke(new Action(() =>
{
StatusTextBox.Text = message;
}));
}
}
public class BuildCustomer
{
public static void StartTask()
{
var action = new Action<object>(BuildCustomer);
var task = new Task(() => action(buildDetails));
task.Start();
task.Wait();
}
private void BuildCustomerDetails(object buildDetails)
{
Common.WriteToDatabase();
}
}
public class Common
{
public delegate void MessageLogDelegate(string message);
public static event MessageLogDelegate SendMessage;
public static void WriteToDatabase()
{
SendMessage("Some status message to write back to the GUI");
}
}
【问题讨论】:
-
@CamiloTerevinto
StartNew在这种情况下,因为它是 4.0,而不是 4.5,但除此之外,是的。 -
我认为 Task.Run() 可能对您不可用,但 Task.StartNew() 应该可用,我会使用它。此外,您还有一些我认为编译器应该捕捉到的错误。
-
它会冻结,因为
.Wait()是一个阻塞调用,并且在任务完成之前不允许 UI 线程执行任何其他操作。如果您愿意,可以在 .Net 4 中使用 async/await:blogs.msdn.microsoft.com/bclteam/2012/10/22/… -
我建议阅读这些文章 Task.Run Etiquette Examples: Don't Use Task.Run for the Wrong Thing Task.Run Etiquette Examples: Don't Use Task.Run in the Implementation 从您的课程中删除 Task 并在您的按钮单击事件处理程序中使用 Task.StartNew
-
我建议阅读 Stephen Cleary 的 Don't Block on Async Code。
标签: c# async-await task-parallel-library