What the error is trying to tell you is that it is illegal to create or manipulate visual controls (such as Grid
) on a thread other than the interface thread.
In this case, the problem is that Task.Run()
executes the BrowserAsync
method in a different thread, so you can not and should not create a Grid
there. In fact, you should not run a MessageBox.Show()
there either. Basically, you can not do anything in that method that wraps interface actions.
It's hard to come up with an appropriate solution other than to tell you that you can not do this, because it's obvious that your code is just a test and does nothing for now.
But if the intention is to execute a long job in the BrowserAsync
method in a different thread so that the interface does not get stuck, that's fine. But you will have to limit yourself to doing and accumulating the result of this work using some structure that is not an interface control and then returning this result to the main interface thread, where there, you can use this result to make modifications to the interface controls .
For example, adjusting your situation a bit, let's say that when you click on the button what you want to do is a long calculation whose result you want to assign to a textbox.
Similar to your code, we might try to do the following:
botontest.Click +=
async (src, args) =>
{
await Task.Run(() => CalculoLargo());
};
private void CalculoLargo() {
Thread.Sleep(30000); // simulando un cálculo largo
int resultado = 100;
textbox1.Text = $"Resultado del cálculo: {resultado}"; // error!!
}
But the statement that tries to assign the result to the textbox is not legal for the reasons already mentioned.
Rather, the correct way to perform the calculation on a different thread and then assign the result to the textbox is like this:
botontest.Click +=
async (src, args) =>
{
int resultado = await Task.Run(() => CalculoLargo());
textbox1.Text = $"Resultado del cálculo: {resultado}";
};
private int CalculoLargo() {
Thread.Sleep(30000); // simulando un cálculo largo
return 100;
}
As you can see, the costly part is still done in a different thread so as not to break the interface thread. But when you have to assign the result to a visual control (textbox), you have to do it in the interface thread. In this example, this is achieved by doing that part after of await Task.Run()
, when the code there is executed in the interface thread.
I hope this example gives you a model of how you can achieve your goal without receiving the error.