Запустите функцию после завершения задачи
Я хочу запустить функцию асинхронно, чтобы предотвратить зависание пользовательского интерфейса. Здесь событие нажатия кнопки.
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());
}