【发布时间】:2017-06-23 22:12:20
【问题描述】:
我的现有系统有几个长时间运行的操作。我希望找到一种简单的方法来将这些操作包装在任务中并给用户一个忙碌状态通知。
这是使用 .net 3.5,我使用的是 TPL 后端端口。不幸的是,这里不能使用 async/await。
我试图以如下所示的简单测试形式提出解决方案,但我遇到了一些问题。
下面的方法只显示前 2-3 个任务,之后 UI 不会更新,直到所有任务都完成。这是为什么呢?
private void RunTaskUpdateBefore (string msg)
{
UpdateUI (msg);
Task task = Task.Factory.StartNew (() =>
{
// simulate some work being done
Thread.Sleep (1000);
});
task.Wait ();
}
我希望这个方法可以工作,但在所有任务完成之前不会更新 UI
private void ChildTaskExternalWait (string msg)
{
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext ();
Task task = Task.Factory.StartNew (() =>
{
Task.Factory.StartNew (() =>
{
UpdateUI (msg);
}, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
// simulate some work being done
Thread.Sleep (1000);
});
task.Wait (); // I assume this is the problem
}
以下方法效果很好,但我不确定是否可以在我的项目中使用它。这是一个相当大的复杂系统,操作发生在许多不同的类中,并且由我们无法修改的遗留系统控制。我假设我必须尝试创建某种全局任务队列来执行此操作?
private Task RunTaskInternalWaitOnPrevious (string msg, Task t1 = null)
{
var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext ();
Task task = Task.Factory.StartNew (() =>
{
if (t1 != null)
{
t1.Wait ();
}
Task.Factory.StartNew (() =>
{
UpdateUI (msg);
}, System.Threading.CancellationToken.None, TaskCreationOptions.None, uiScheduler);
// simulate some work being done
Thread.Sleep (2000);
});
return task;
}
我的测试表单实现:
private void button1_Click (object sender, EventArgs e)
{
// Only displays the first 2-3 tasks. After that UI doesn't get updated until all are complete
RunTaskUpdateBefore ("Task 1");
RunTaskUpdateBefore ("Task 2");
RunTaskUpdateBefore ("Task 3");
RunTaskUpdateBefore ("Task 4");
RunTaskUpdateBefore ("Task 5");
RunTaskUpdateBefore ("Task 6");
RunTaskUpdateBefore ("Task 7");
// this works with any number of tasks
// Unfortunately I'm not sure if I can use it in my application (see above notes)
//var t1 = RunTaskInternalWaitOnPrevious ("Task 1");
//var t2 = RunTaskInternalWaitOnPrevious ("Task 2", t1);
// and so on
}
private void UpdateUI (string msg)
{
this.textBox1.Text += msg;
this.textBox1.Text += System.Environment.NewLine;
}
更新/澄清
*我的任务不能并行运行。
*我想通知用户每个步骤都在完成工作。
*任务运行时不会发生其他 UI 输入。
任务并没有集中到特定的代码段,而是在各处发生。我不确定如何描述我的情况,对不起。
【问题讨论】:
-
我认为此时我需要从一个更短的示例重新开始。
标签: c# winforms .net-3.5 task-parallel-library