У меня есть следующая проблема. У меня синхронное действие .Save(), которое длится довольно много минут. Я не могу сделать это async (сторонняя библиотека), поэтому, чтобы поддерживать пользовательский интерфейс, я использую его все в Task.Run()
.while цикл во время ожидания для задачи async
Я хотел бы сообщить о прогрессе, так что пользователь видит, что что-то происходит - и я хочу, чтобы сделать его в ярлыке Status - простой и старой школы добавлять и удалять точки в строку, вроде как
Подождите.
Wait ..
Подождите ...
Подождите.
Я не знаю, как это сделать простым способом - я думал о цикле while
, который прерывался бы после завершения задачи, но, похоже, не работает - либо пользовательский интерфейс заблокирован, либо статус метка не обновляется.
Я попробовал несколько вещей, например:
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);
}
Итак, каков правильный путь?
Lets попробовать вторую попытку на этот вопрос, как я полагаю, никто не будет смотреть на свежий вопрос с -3 голосов в любом случае. Надеюсь, что все downvoters теперь будут делать что-то более конструктивное :) – Bartosz
Вам нужно указать время потока пользовательского интерфейса, чтобы выполнить его пересылку сообщений. Если вы не можете изменить исходный метод для отчета о прогрессе, одним из вариантов является периодическое обновление состояния на основе таймера. –
Переменная 'done', которую вы можете использовать для сигнализации двух потоков, может не работать, потому что некоторое значение времени не доступно для другого потока. –