以下代码抽象出我的实际任务,即遍历位图中的每个像素。
myButtonCommand.execute(async () => {
await Task.Run(() => {
while(i++<1000000) {
// do some work
if(i % 1000 == 0) // only update on every 1000th iteration
{
ProgressChanged.Invoke(this, i); // fire update event
Thread.Sleep(n);
}
}
});
});
提供给myButtomCommand.execute
的lambda在UI线程上运行。但是由于不能保证在UI线程上运行任务,这并不意味着调用Thread.Sleep(n)
可能会冻结UI线程吗?
根本问题是我需要更新进度条而不执行Thread.Sleep(n)
,当任务正在旋转时,UI线程被阻止。
现在,我最终做的是使用Thread.Sleep(0)
,因此只有在另一个线程需要运行时它才会进入休眠状态。但我不明白为什么首先使用Thread.Sleep(n)
是必要的,因为至少在我的测试中,它至少在一个单独的线程上。
所以我对两件事感到困惑:
Thread.Sleep(n)
是否安全?Thread.Sleep(n)
需要更新UI才能在单独的线程上运行任务?答案 0 :(得分:1)
并且没有执行Thread.Sleep(n),当任务正在旋转时,UI线程被阻塞。
这意味着你在这里只是召唤了太多的Invokes GUI线程没有被“阻止”,只是过度工作。
另一种可能更好的方法
//if(i % 1000 == 0)
if(i % 1000000 == 0)
答案 1 :(得分:1)
类似,我可以向你保证用户界面不会冻结 在异步上查找进度。
await Task.Delay(500);
可能就是您所需要的一切。
async Task<int> TaskDelayAsync(CancellationToken ct, IProgress<int> progress)
{
int i = 0;
while (true)
{
i++;
//Debug.WriteLine(i);
progress.Report(i);
ct.ThrowIfCancellationRequested();
await Task.Delay(500);
}
return i;
}