Мне нужно запустить некоторый код, не блокируя основной поток пользовательского интерфейса, но основной поток пользовательского интерфейса должен знать, когда задача завершена, чтобы пользовательский интерфейс мог продолжить выполнение соответствующих действий. Ниже то, что я делаю
private bool _isTaskStarted = false;
public bool IsTaskStarted
{
get { return _isTaskStarted; }
set { _isTaskStarted = value; OnPropertyChanged(); }
}
private async void MethodCalledOnButtonClick()
{
IsTaskStarted = true; //this will tell UI to show progress
string result = await MyTimeConsumingMethod(param1, param2)
IsTaskStarted = false;
}
private async Task<string> MyTimeConsumingMethod(List<string> collection, int count)
{
Task<string> t = Task.Run(()=>
{
//Task Delay is not working
Task.Delay(2000);//Delay this task for 2 sec
//Some time consuming code
//Will create a pdf document and return a created pdf full path
string returnValue = createdPdfFullPath;//Will have some value
return returnValue ;
});
t.Wait();
return await Task.FromResult(t.Result);
}
Элемент пользовательского интерфейса может быть компонентом ProgressRing.
<mah:ProgressRing
IsActive="{Binding IsTaskStarted , Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
Даже если у меня есть отложенная задача на x секунд, элемент пользовательского интерфейса, включенный isTaskStarted, не виден. Но если я не установлю его значение на false, я увижу этот элемент. Но я хочу, чтобы этот элемент был виден во время выполнения MyTimeConsumingMethod
Как мне решить эту проблему? Может ли кто-нибудь указать мне правильное направление.
isTaskStarted
— это локальная переменная, так как же поток пользовательского интерфейса будет читать значение? Если вы хотите, чтобыMyTimeConsumingMethod
был асинхронным, не используйте Task.Wait внутри — это означает, что это совсем не асинхронно. Используйтеreturn await Task.Run(...);
- person Xerillio   schedule 05.07.2021async
на самом деле не является асинхронным. Проблемными операторами являютсяt.Wait();
иreturn await Task.FromResult(t.Result)
, которые оба блокируют до тех пор, пока задача не завершится, и вообще никаких асинхронных аспектов. Просто полностью удалите эти операторы, избавьтесь отasync
в объявлении метода и верните значениеt
. - person Peter Duniho   schedule 05.07.2021IsTaskStarted
является свойством, то покажите, как вы его объявили и как задали привязку к нему в View. - person EldHasp   schedule 05.07.2021IsActive
. Как это работает? Если true, элементmah:ProgressRing
виден. Если ложно, не видно. Это верно? - person EldHasp   schedule 05.07.2021return await Task.Run (....);
- person EldHasp   schedule 05.07.2021return await Task.Run()
в этом примере бессмысленно. Как я уже отмечал в своем комментарии выше, метод даже не обязательно должен бытьasync
. Ему просто нужно вернуть объектTask<string>
, возвращенный вызовом методаTask.Run()
. - person Peter Duniho   schedule 05.07.2021return await Task.Run (....);
, всегда будет неправильно. Если это единственный оператор в методе, никогда нет смысла ждать выполнения задачи. Лучше всегда просто вернуть задачу. - person Peter Duniho   schedule 05.07.2021MyTimeConsumingMethod
в этом случае избыточен. И обычного метода, возвращающего строку, достаточно. Но чтобы показать правильную реализацию, нужно изменить как само объявление метода, так и то, как он вызывается в методеMethodCalledOnButtonClick
. На мой взгляд, формат комментария не дает возможности для таких исправлений. Если бы вопрос не был закрыт, то можно было бы показать необходимые изменения в ответе. - person EldHasp   schedule 06.07.2021