у меня есть функция длительного запуска¹:
public string FindPasswordFromHash(String hash)
{
...
}
который называется как:
private void Button1_Click(object sender, EventArgs e)
{
PasswordTextBox.Text = FindPasswordFromHash(HashTextBox.Text);
}
Теперь я хочу преобразовать его в асинхронный шаблон делегата BeginInvoke / EndInvoke:
private void Button1_Click(object sender, EventArgs e)
{
MyAsyncDelegate asyncDelegate = new MyAsyncDelegate(HashTextBox.Text);
asyncDelegte.BeginInvoke(hash, CompleteCallback, null);
}
private void CompleteCallback(IAsyncResult ar)
{
MyAsyncDelegate asyncDelegate = ((AsyncResult)ar).AsyncDelegate;
PasswordTextBox.Text = asyncDelegate.EndInvoke(asyncResult);
}
delegate string MyAsyncDelegate(String hash);
Конечно, это не работает из-за неплотной абстракции способа реализации асинхронных делегатов:
"Поперечная операция недопустима:
Доступ к элементу управления PasswordTextBox
из нити, отличной от нити это
был создан на ".
Учитывая, что шаблон асинхронного делегата был изобретен для преобразования длительных операций в асинхронные операции - как правильно использовать BeginInvoke / EndInvoke в качестве замены для синхронного вызова?
И, более конкретно, каков метод для принудительного обратного вызова для маршалинга обратно в вызывающий поток?
¹ Придумано название функции, например