我有以下问题。我有一个同步.Save()动作,需要花费几分钟才能完成。我无法使其成为异步(第三方库),因此为了保持UI响应,我在Task.Run()
中使用它。
我想报告进度,以便用户看到正在发生 - 并且我想在状态标签中创建它 - 一个简单的旧学校附加并删除点到字符串,排序喜欢的
等等。
等待..
稍候...
等待。
我不知道如何以一种简单的方式做到这一点 - 我想到一个while
循环会在任务结束时中断,但它似乎不起作用 - UI被阻止或状态标签不会更新。
我尝试了几件事,例如:
bool done = false;
Task.Run(() =>
{
Exporter.DoLongSyncTask();
}).ContinueWith(r => done = true);
StatusLabel = ".";
while (!done)
{
if (StatusLabel == "")
StatusLabel = ".";
else if (StatusLabel == ".")
StatusLabel = "..";
else if (StatusLabel == "..")
StatusLabel = "";
}
(StatusLabel是一个实现了INotifyPropertyChanged的属性,它工作正常)
更复杂
private async Task<bool> DoTheWork()
{
await Task.Run(() => TheFile.Save());
return true;
}
private string ReportProgress(string status)
{
if (status == ".")
status = "..";
else if (status == "..")
status = "...";
else if (status == "...")
status = ".";
MyProgress.Report(new InDesignExporterProgress { StatusInfo = status });
return status;
}
private string ReportProgress(string status)
{
if (status == ".")
status = "..";
else if (status == "..")
status = "...";
else if (status == "...")
status = ".";
MyProgress.Report(new SomeProgressClass { StatusInfo = status });
return status;
}
以上从这里调用
bool done = false;
Task.Run(() =>
{
done = DoTheWork().Result;
});
string status = ".";
while (!done)
{
status = ReportProgress(status);
}
那么,什么是正确的方法?
答案 0 :(得分:1)
要知道任务是否已完成,请检查IsCompleted属性的值。
while (!task.IsCompleted)
{
// ...
}
但是,对于我认为你想要的,我会做这样的事情:
using (var timer = new System.Windows.Forms.Timer())
{
timer.Tick += (s, e) =>
{
if (StatusLabel == "")
StatusLabel = ".";
else if (StatusLabel == ".")
StatusLabel = "..";
else if (StatusLabel == "..")
StatusLabel = "";
};
timer.Interval = 100;
timer.Enabled = true;
await Task.Run(() => Exporter.DoLongSyncTask);
}
答案 1 :(得分:0)
我认为你使用while循环阻止你的UI线程,因为我猜它在该线程上运行。
我建议你尝试将这样的while循环和方法签名更改为async Task
public async Task DoSomething(){
bool done = false;
Task.Run(() =>
{
Exporter.DoLongSyncTask();
}).ContinueWith(r => done = true);
StatusLabel = ".";
while (!done)
{
if (StatusLabel == "")
StatusLabel = ".";
else if (StatusLabel == ".")
StatusLabel = "..";
else if (StatusLabel == "..")
StatusLabel = "";
await Task.Delay(200);
}
}