我在处理结束时有大数据处理和结果显示到文本框。
问题是表单变得不可移动几秒钟,它不是“没有响应”挂起状态或完全冻结,我能够在执行期间用按钮停止进程。但我不能在桌面上移动表格几秒钟的处理。
我不需要在处理期间显示结果,它会以Environment.NewLine
作为完整列表显示在计算和计算中。但我想以某种方式避免GUI的短时间固定状态
我尝试将具有UI操作的文本框显示更新到任务中:
private void button1_Click(object sender, EventArgs e)
{
Process();
Display();
}
private void Display()
{
Task.Factory.StartNew(() => {
Invoke((Action)(() =>
{
/// Textbox output
}));
});
}
现在我可以在此过程中移动窗体,但是如果在窗体上按下鼠标,则在释放鼠标按钮之前它不允许显示结果。另外我不确定这种方法有多安全。我试图找出哪种Task方法对于这种情况更好,更有用。
答案 0 :(得分:3)
Invoke
方法,任务正在后台运行。以这种方式运行操作没有任何意义。
async
StartNew
方法,而是使用Task.Run
await
那个任务Display
方法所以你的代码看起来像这样:
private async void button1_Click(object sender, EventArgs e)
{
// run process in background
await Task.Run(() => Process());
// return to UI context
Display();
}
private void Display()
{
// Textbox output
}
答案 1 :(得分:1)
尝试使用Task
这样的对象:
Task myTask = new Task(new Action(()=>
{
// your operations code here
}));
myTask.ContinueWith(c=>
{
yourControlName.BeginInvoke(new Action(()=>
{
// update control here
}));
});
myTask.Start();
请注意,您还可以通过在Task
之前创建任务来完成其工作,并在任务开始后将其部署在其中并在任务启动后showdialoging
Begininvoke会发信号通知创建控件的线程并对ui进行更改,事情是
如果您没有指定控件名称,它将在此处定位表单,并且它们在程序中共享相同的创建者线程,但在复杂的多线程应用程序中则不一样。
修改强> 感谢VMAtm指出不建议使用Task构造函数,我做了一点挖掘并发现了这个: msdn blog
随着说 在你的情况下,正确的做法是:
Task.Factory.StartNew( ()=>
{
//computing here
yourControlName.BeginInvoke(new Action(()=>
{
// update control here
}));
}));
// or display() here if you dont have to do it using begininvoke
<强> 无论其 强>
根据{{3}} StartNew
是危险的(再次感谢VMAtm)
在您的情况下,最好的方法是:
await Task.Run(() => Process());
Display();
请注意,所有这些都适用于您的情况,这只是理想情况下的哪一个问题......