C # Progress & lt; string & gt; callback не вызывается после IProgress.Report называется [duplicate]

Использовать MouseUp !!

    private void button6_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            MessageBox.Show("LEFT");
        }
        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            MessageBox.Show("RIGHT");
        }
    }
3
задан Lemonseed 9 February 2016 в 01:02
поделиться

1 ответ

Когда вы выполняете метод async, он начинает работать синхронно до тех пор, пока он не достигнет оператора await, а остальная часть кода будет выполняться асинхронно, а выполнение вернется к вызывающему.

В вашем код callCount() запускается синхронно с await task, затем возвращается к Main() методу, и поскольку вы не дожидаетесь завершения метода, программа заканчивается без метода count().

Вы можете увидеть желаемое поведение, изменив тип возвращаемого значения на Task и вызывая Wait() в методе Main().

static void Main(string[] args)
{
    callCount().Wait();
}

static void count()
{
    for (int i = 0; i < 5; i++)
    {
        System.Threading.Thread.Sleep(2000);
        Console.WriteLine("count loop: " + i);
    }
}

static async Task callCount()
{
    Task task = new Task(count);
    task.Start();
    for (int i = 0; i < 3; i++)
    {
        System.Threading.Thread.Sleep(1000);
        Console.WriteLine("Writing from callCount loop: " + i);
    }
    Console.WriteLine("just before await");
    await task;
    Console.WriteLine("callCount completed");
}

EDIT: Так выполняется ваш код:

(для лучшего понимания изменения типа CallCount() возвращаются к Task)

  1. программа запускается с использованием метода Main().
  2. CallCount() .
  3. создается задача, все это в том же потоке.
  4. Затем задача запускается. На этом этапе создается новый поток, запускающий параллельный метод Count().
  5. Выполнение продолжается в CallCount (), для цикла выполняется и «just before await» печатается.
  6. Затем достигается await task;. Это когда роль асинхронного ожидания играет свою роль. await не похож на Wait(), он не блокирует текущий поток до тех пор, пока задача не завершится, но вернет управление исполнением в метод Main() и все остальные инструкции в CallCount() (в данном случае только Console.WriteLine("callCount completed"); ) будет исполнена после завершения задачи.
  7. В Main() вызов CallCount() возвращает Task (с оставшимися инструкциями CallCount() и исходной задачей), и выполнение продолжается .
  8. Если вы не дождались завершения этой задачи, выполнение в Main() продолжит завершение работы программы и уничтожаемых задач.
  9. Если вы вызываете Wait() (если CallCount() недействительно, чтобы вы не ожидали выполнения задачи), вы позволяете завершить задачу, удерживая ее в Main() для выполнения Count() и печатаемой «callCount».

Если вы хотите дождаться окончания задания счетчика в CallCount(), не возвращаясь к методу Main(), вызовите task.Wait();, вся программа будет ждать Count(), но это не то, что await будет делать.

Эта ссылка подробно описывает шаблон асинхронного ожидания.

H opes, эта диаграмма рабочего процесса вашего кода помогает вам.

10
ответ дан Arturo Menchaca 17 August 2018 в 10:19
поделиться
  • 1
    Да, я пробовал это так, увидев другой подобный вопрос и ответ на переполнение стека, но он все равно делает то же самое. Я сделал это точно так же, как у вас с Task в качестве возвращаемого типа. – jaykum 9 February 2016 в 02:14
  • 2
    Я вижу, что оба моих сценария выполняются, но это похоже на игнорирование «ожидающей задачи». Должна ли она удерживать выход из callCount, пока счет не будет выполнен? – jaykum 9 February 2016 в 02:26
  • 3
    «Когда вы выполняете метод async, он начинает работать синхронно до тех пор, пока не достигнет оператора ожидания, тогда остальная часть кода будет выполняться асинхронно, а выполнение вернется к вызывающей стороне». Это не похоже на то, что я выполняю задачу. Старт () Я вижу чередующееся выполнение Writeline, как если бы выполнялись циклы count () и callCount (). Когда я нажимаю кнопку ожидания, моя программа завершает count (). – jaykum 9 February 2016 в 02:32
  • 4
    @jaykum Я отредактировал свой ответ, чтобы показать, как работает шаблон async-await в вашем коде. Когда я говорю, что метод запускается синхронно, я ссылаюсь на методы Main () и CallCount (), а не на задачу – Arturo Menchaca 9 February 2016 в 16:43
  • 5
    Большое спасибо Артуро за подробное объяснение и помощь. Я, наконец, понял основы и заработал свою программу. Ключевое различие между ожиданием и ожиданием () было важно для понимания. Я немного поиграл с этим с вашей помощью. Я действительно ценю, что все в stackoverflow настолько щедры, что им помогает время. Отличное сообщество. – jaykum 9 February 2016 в 18:29
Другие вопросы по тегам:

Похожие вопросы: