[РЕДАКТИРОВАТЬ] Перефразированный и упрощенный весь пост [/ EDIT]
В этом блоге в качестве примера использования объекта SynchronizationContext для выполнения Задачи в потоке пользовательского интерфейса приводится следующее (я немного упростил это):
Task.Factory.StartNew(() =>"Hello World").ContinueWith(
task => textBox1.Text = task.Result,
TaskScheduler.FromCurrentSynchronizationContext());
Я могу повторить эти результаты в новом проекте, безопасно обновив пользовательский интерфейс, но по какой-либо причине в моем текущем проекте (даже если он работал работает) я не могу. Я получаю стандартное исключение "Вам не разрешено обновлять пользовательский интерфейс из неправильного потока".
Мой код (в MainForm_Load (...)) похож на этот, который работает в новом Project с textBox1, добавленным в основную форму, но не работает в моем текущем проекте:
var one = Task.Factory.StartNew(
() => "Hello, my name is Inigo Montoya");
var two = one.ContinueWith(
task => textBox1.Text = one.Result,
TaskScheduler.FromCurrentSynchronizationContext());
У любого есть мысли о том, что может быть гонгом.
[EDIT]
Я проследил ошибку до создания экземпляра объекта, который использует форму, чтобы запросить у пользователя информацию для входа в систему. Ошибка происходит только тогда, когда форма была показана. (Если я верну жестко запрограммированное значение до того, как Show
этой формы произойдет, все будет работать нормально).
Новый вопрос: Как я могу получить SynchronizationContext для формы, которую я создаю, если ее собственный конструктор отображает другую форму до того, как она была показана? Вот как вы можете воспроизвести происходящее:
1) Создайте две формы: Form1 с TextBox
и Form2 с Button
2) Создать класс OwnedBy1Uses2
Form1
public partial class Form1 : Form
{
OwnedBy1Uses2 member;
public Form1()
{
InitializeComponent();
member = new OwnedBy1Uses2();
}
private void Form1_Load(object sender, EventArgs e)
{
var ui = TaskScheduler.FromCurrentSynchronizationContext();
Task<string> getData = Task.Factory.StartNew(
() => "My name is Inigo Montoya...");
Task displayData = getData.ContinueWith(
t => textBox1.Text = t.Result, ui);
}
}
Form2
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
DialogResult = System.Windows.Forms.DialogResult.Cancel;
}
private void button1_Click(object sender, EventArgs e)
{
DialogResult = System.Windows.Forms.DialogResult.OK;
Hide();
}
}
OwnedBy1Uses2
class OwnedBy1Uses2
{
int x;
public OwnedBy1Uses2()
{
using (Form2 form = new Form2())
{
if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
x = 1;
}
else
{
x = 2;
}
}
}
}