How to get the synchronization context for the second form shown

[EDIT] Re-phrased and simplified message of purpose [/ EDIT]

In this blog post, the following (I simplified it a bit) provides an example of using the SynchronizationContext object to run the Task on UI thread:

Task.Factory.StartNew(() =>"Hello World").ContinueWith(
            task => textBox1.Text = task.Result,
            TaskScheduler.FromCurrentSynchronizationContext());

I can repeat these results in a new project, safely updating the interface, but for some reason in my current project (even though it works) I cannot. I get the standard exception "Unable to update user interface from the wrong stream."

My code (in MainForm_Load (...)) is similar to this one, which works in a new w / textBox1 project added to the main form, but does not work in my current project:

var one = Task.Factory.StartNew(
        () => "Hello, my name is Inigo Montoya");
var two = one.ContinueWith(
        task => textBox1.Text = one.Result,
        TaskScheduler.FromCurrentSynchronizationContext());

Does anyone have a thought that there might be a gong.

[EDIT]

I traced the error back to the instance of the object, which uses the form to ask the user for login information. The error occurs only when the form is displayed. (If I return the hard-coded value before Form Showhappens, it all works fine.)

New question: how can I get a SynchronizationContext for the form that I create if its own constructor displays another form before it is shown? Here, as you can reproduce what happens:

1) Create two forms: Form1 s TextBoxand Form2 sButton

2) Create a class 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;
            }
        }
    }
}
+3
1

. SynchronizationContext.Current ( FromCurrentSynchronizationContext SynchronizationContext.Current, null, - ).

, , FromCurrentSynchronizationContext, , - Form.Load WinForms Window.Loaded WPF.

Edit:

WinForms , Form.Load - Win32, Handle. , , .

2 ( ):

, , ShowDialog Application.Run. ShowDialog - , . SynchronizationContext.Current ShowDialog, , a WindowsFormsSynchronizationContext , , -WinForms SynchronizationContext . ( ShowDialog) Load .

+4

Source: https://habr.com/ru/post/1781728/


All Articles