Задача Winforms заблокирована в потоке пользовательского интерфейса - PullRequest
0 голосов
/ 29 октября 2019

У меня есть ситуация, когда я не могу по-настоящему обновить свое приложение до асинхронного полностью , поэтому я надеюсь найти промежуточное решение.

Во-первых,Я фиксирую контекст пользовательского интерфейса, когда форма обновляется.

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");
}

Есть другие идеи, какими будут промежуточные решения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...