У меня есть ситуация, когда я не могу по-настоящему обновить свое приложение до асинхронного полностью , поэтому я надеюсь найти промежуточное решение.
Во-первых,Я фиксирую контекст пользовательского интерфейса, когда форма обновляется.
private readonly TaskScheduler uiSched;
public Form1()
{
// capture UI Thread
uiSched = TaskScheduler.FromCurrentSynchronizationContext();
InitializeComponent();
}
Это симуляция кода, но в основном из потока, не являющегося графическим интерфейсом, я хочу обновить графический интерфейс пользователя и ждатьэто должно быть сделано.
private void button1_Click(object sender, EventArgs e)
{
var outerTask = Task.Run(() =>
{
// appears to be never scheduled
return Task.Factory.StartNew(() =>
{
this.Text = $"Changed";
}, CancellationToken.None, TaskCreationOptions.None, uiSched);
});
outerTask.Wait(); // wait until GUI is done, before proceeding.
Debug.WriteLine($"Done");
}
По сути, я заблокирован ожиданием внешней задачи.
У меня есть решение, показанное ниже, которое, кажется, работает, но я не понимаю, почему оно работает.
private void button1_Click(object sender, EventArgs e)
{
var outerTask = Task.Run(async () =>
{
await Task.Yield(); // why this makes it work?
return Task.Factory.StartNew(() =>
{
this.Text = $"Changed {DateTime.Now}";
}, CancellationToken.None, TaskCreationOptions.None, uiSched);
});
//wait for GUI
outerTask.Wait();
Debug.WriteLine($"Done");
}
Конечно, в идеальном мире это было бы полностьюасинхронно, но у меня сейчас нет такой возможности.
// Proper Solution:
private async void button1_Click(object sender, EventArgs e)
{
var outerTask = Task.Run(async () =>
{
await Task.Factory.StartNew(() =>
{
this.Text = $"Changed {DateTime.Now}";
}, CancellationToken.None, TaskCreationOptions.None, uiSched).ConfigureAwait(false);
});
await outerTask.ConfigureAwait(false);
Debug.WriteLine($"Done");
}
Есть другие идеи, какими будут промежуточные решения?