3

I am very new to WPF. And just started learning threading.

Here is my scenario: I've created a program with a button named START. When start button is clicked it starts to do some complex task in different thread. Just before beginning the complex task it also creates a UI elements in another STA thread (technically i don't know what i am saying).

Here is a sample code:

// button click event
private void button1_Click(object sender, RoutedEventArgs e)
{
    System.Threading.Thread myThread = new System.Threading.Thread(
        () => buttonUpdate("Hello "));
    myThread.Start();
}

private void buttonUpdate(string text)
{
    System.Threading.Thread myThread = new System.Threading.Thread(createUI);
    myThread.SetApartmentState(System.Threading.ApartmentState.STA);

    // set the current thread to background so that it's existant will totally 
    // depend upon existance of main thread.
    myThread.IsBackground = true;
    myThread.Start();

    // Please don't read this loop it's just for my entertainment!
    for (int i = 0; i < 1000; i++)
    {
        System.Threading.Thread.Sleep(100);
        button1.updateControl(new Action(
            () => button1.Content = text + i.ToString()));
        if (i == 100)
            break;
    }

    // close main window after the value of "i" reaches 100;
    this.updateControl(new Action(()=>this.Close()));
}

// method to create UI in STA thread. This thread will be set to run 
// as background thread.


 private void createUI()
 {
     // Create Grids and other UI component here
 }

The above code succesfully does what i want to do. But do you think it's the correct way? so far i don't have any problem here.

EDIT: OOps I forgot to mention this class:

public static class ControlException
{
    public static void updateControl(this Control control, Action code)
    {
        if (!control.Dispatcher.CheckAccess())
            control.Dispatcher.BeginInvoke(code);
        else
            code.Invoke();
    }
}
Shimmy Hacked
  • 459
  • 5
  • 10
user995387
  • 355
  • 3
  • 8
  • 17
  • Might help if you actually understand what you are saying. Do some research come back when you understand what a STA thread means. – Security Hound Dec 29 '11 at 18:40

3 Answers3

2

If you are using .NET 4.0 you might want to consider using the Task class from the Task parallel library. Read into it since you say you are new to threading. It's much more flexible to use.

Also I think that this link could be very helpful to you:

http://www.albahari.com/threading/

TheBoyan
  • 6,802
  • 3
  • 45
  • 61
  • I was not able to work with UI Elements using Task. see this: http://stackoverflow.com/questions/8665158/a-very-basic-explanation-for-threading-in-wpf – user995387 Dec 29 '11 at 18:02
  • 1
    @user995387 - You can use the TaskScheduler.FromCurrentSynchronizationContext Method to get a TaskScheduler for the current synchronization context. Check out this post: http://stackoverflow.com/questions/5971686/how-to-create-a-task-tpl-running-a-sta-thread – TheBoyan Dec 29 '11 at 18:04
  • Thank you that was a great help. I'll try this way around. – user995387 Dec 29 '11 at 18:08
2

There seems to be no good reason to use 2 threads.

You should be able to execute the createUI() on the main thread. That'll be complicated enough when it becomes time to fill those controls.

H H
  • 263,252
  • 30
  • 330
  • 514
1

Only one thread can interact with the UI. If you are going to add a control to a page or windows then you must use the thread that created the page or window. The typical scenario is to use threading to create expensive data or object in the background and then on the callback (running on the primary thread) retrieve the result and bind appropriate data to the UI. Look at using BackgroundWorker as it takes care of a lot of the threading detail for you. http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx Why do you want to create UI objects on another thead?

paparazzo
  • 44,497
  • 23
  • 105
  • 176