Запустите функцию после завершения задачи

Я хочу запустить функцию асинхронно, чтобы предотвратить зависание пользовательского интерфейса. Здесь событие нажатия кнопки.

private void btnEncrypt_Click(object sender, EventArgs e)
{
    // Create new Vigenere object instant
    cryptor = new Vigenere(txtPassword.Text, txtBox.Text);

    // Run encryption async
    Task<string> T = new Task<string>(cryptor.Encrypt);
    T.Start();
}

Теперь я хочу, чтобы следующая функция вызывалась, когда Задача T заканчивается с возвращаемым значением в качестве параметра, подобного этому:

private void Callback(string return_value)
{
    txtBox.Text = return_value

    // Some other stuff here
}

Как этого добиться?

3 ответа

Что вы могли бы сделать, это использовать ContinueWith(Action<Task>) метод.

Так что у вас будет что-то вроде

Task<string> t = new Task<string>(cryptor.Encrypt);
T.Start();

Task continuationTask = t.ContinueWith((encryptTask) => {
    txtBox.Text = encryptTask.Result;
    ...
})

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

Сначала добавьте async на ваше событие нажатия кнопки. Пытаться:

private async void btnEncrypt_Click(object sender, EventArgs e)
{
     cryptor = new Vigenere(txtPassword.Text, txtBox.Text);
     await Task.Run(() => cryptor.Encrypt()).ContinueWith(result => { Callback(result.Result); });
}

Вы хотите использовать Task.Run и жду на нем. Это заставит метод выполняться в потоке пула потоков и назначит возвращенную строку TextBox после его завершения:

private async void btnEncrypt_Click(object sender, EventArgs e)
{
     cryptor = new Vigenere(txtPassword.Text, txtBox.Text);
     textBox.Text = await Task.Run(() => cryptor.Encrypt());
}

Ты можешь использовать async await как это:

private async void btnEncrypt_Click(object sender, EventArgs e)
{
    // Create new Vigenere object instant
    cryptor = new Vigenere(txtPassword.Text, txtBox.Text);

    // Run encryption async
    txtBox.Text = await Task.Run(() => cryptor.Encrypt());
}
Другие вопросы по тегам