O Jean
O Jean

Reputation: 105

STA for non created Thread/Task

I made a simple async method for a loading animation while code runs. The code which runs adds controls to stackpanel.

in Page_Loaded Event i just have:

Test();

In Test() i have

private async void Test()
{
   testbtn.Visibility = Visibility.Visible;
   await Task.Run(() => LoadAll());
   testbtn.Visibility = Visibility.Collapsed;
}

and in LoadAll() are DockPanels etc. for exmaple:

DockPanel headerpanel = new DockPanel();
headerpanel.LastChildFill = false;

When Running this i get an error because the Thread isnt a STA Thread. How can I make it STA even if i dont created a Thread. (just have await Task.Run(() => LoadAll());)

Do I have to create a big Thread etc. only for a simple animation bar while code runs?

Upvotes: 0

Views: 37

Answers (2)

Stephen Cleary
Stephen Cleary

Reputation: 456587

Do I have to create a big Thread etc. only for a simple animation bar while code runs?

No; just don't do UI work on a background thread. Use IProgress<T>/Progress<T> instead, e.g.:

private async void Test()
{
  testbtn.Visibility = Visibility.Visible;
  IProgress<string> progress = new Progress<string>(value => { ... });
  await Task.Run(() => LoadAll(progress));
  testbtn.Visibility = Visibility.Collapsed;
}

and have LoadAll call progress.Report("update") when it wants to update the UI.

Upvotes: 1

Sefe
Sefe

Reputation: 14007

You can run your task in a scheduler that allows you to safely execute UI Code:

private async void Test()
{
    testbtn.Visibility = Visibility.Visible;
    TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
    await Task.Factory.StartNew(() => LoadAll(),
        CancellationToken.None, TaskCreationOptions.None, scheduler);
    testbtn.Visibility = Visibility.Collapsed;
}

Upvotes: 2

Related Questions