I have a following problem. I have a synchronous .Save() action that takes quite a few minutes to complete. I cannot make it async (3rd party library), so to keep the UI responsive, I am using it all in Task.Run().
I would like to report progress so that the users sees that something is happening - and I want to make it in the Status label - a simple and old school append and remove dots to string, sort of like
Wait.
Wait..
Wait...
Wait.
I don't know how to do it in a simple way - I thought of a while loop that would break once the Task ends, but it doesn't seem to work - either the UI is blocked or the status label does not update.
I tried a couple of things, for example:
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 is a property with INotifyPropertyChanged implemented, it works OK)
and more complicated
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;
}
and the above are called from here
bool done = false;
Task.Run(() =>
{
done = DoTheWork().Result;
});
string status = ".";
while (!done)
{
status = ReportProgress(status);
}
So, what's the right way?
donevariable that you can are using to signal two threads might not work because some time value is not immediately available to other thread.task.IsCompleted