С появлением async
и await
теперь возможно частично отказаться от потока пользовательского интерфейса через (ранее) * синхронный блок кода, используя Task.Delay
, например,
private async void myButton_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("scale {0}, location: {1}",
myScaleTransform.ScaleX,
myCanvas.PointToScreen(GetMyByttonLocation()));
myScaleTransform.ScaleX =
myScaleTransform.ScaleY =
myScaleTransform.ScaleX + 1;
await Task.Delay(1); // In my experiments, 0 doesn't work. Also, I have noticed
// that I need to add as much as 100ms to allow the visual tree
// to complete its arrange cycle and for properties to get their
// final values (as opposed to NaN for widths etc.)
Console.WriteLine("scale {0}, location: {1}",
myScaleTransform.ScaleX,
myCanvas.PointToScreen(GetMyByttonLocation()));
}
Я буду честен, я не пробовал это с точным кодом выше, но я использую это в тесных циклах, когда я помещаю много элементов в ItemsControl
, который имеет дорогой шаблон элемента, иногда добавляя небольшая задержка, чтобы дать другим вещам на интерфейсе больше времени.
Например:
var levelOptions = new ObservableCollection<GameLevelChoiceItem>();
this.ViewModel[LevelOptionsViewModelKey] = levelOptions;
var syllabus = await this.LevelRepository.GetSyllabusAsync();
foreach (var level in syllabus.Levels)
{
foreach (var subLevel in level.SubLevels)
{
var abilities = new List<GamePlayingAbility>(100);
foreach (var g in subLevel.Games)
{
var gwa = await this.MetricsRepository.GetGamePlayingAbilityAsync(g.Value);
abilities.Add(gwa);
}
double PlayingScore = AssessmentMetricsProcessor.ComputePlayingLevelAbility(abilities);
levelOptions.Add(new GameLevelChoiceItem()
{
LevelAbilityMetric = PlayingScore,
AbilityCaption = PlayingScore.ToString(),
LevelCaption = subLevel.Name,
LevelDescriptor = level.Ordinal + "." + subLevel.Ordinal,
LevelLevels = subLevel.Games.Select(g => g.Value),
});
await Task.Delay(100);
}
}
В Магазине Windows, когда в коллекции есть хороший переход к теме, эффект весьма желателен.
Люк
- см. Комментарии. Когда я быстро писал свой ответ, я думал о том, чтобы взять синхронный блок кода и затем вернуть поток обратно его вызывающей стороне, в результате чего блок кода становится асинхронным. Я не хочу полностью перефразировать мой ответ, потому что тогда читатели не смогут увидеть, из-за чего мы с Серви спорили.