tweetysat
tweetysat

Reputation: 2403

Visual C# .net 2013 & Threads how-to

I'm normally developping in java but I have now to develop a little wpf application using visual c# 2013 and ... it seems to be more complex than java. So perhaps I will have lot of questions about it.

For the moment I'm working on threads. And my first question is : what is the difference between that two ways for creating threads

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Application.Current.Shutdown();
    }

    private void Threads_Button_Click_1(object sender, RoutedEventArgs e)
    {
        Thread th1 = new Thread(doSomething1);
        th1.Start();

        Thread th2 = new Thread(new ThreadStart(doSomething2));
        th2.Start();
    }
    private void doSomething1()
    {
        Console.WriteLine("Starting doSomething1");
        Thread.Sleep(3000);
        Console.WriteLine("Finishing doSomething1");
    }
    private void doSomething2()
    {
        Console.WriteLine("Starting doSomething2");
        Thread.Sleep(6000);
        Console.WriteLine("Finishing doSomething2");
    }
}

Upvotes: 1

Views: 311

Answers (2)

Sven Grosen
Sven Grosen

Reputation: 5636

Storment's answer is correct, but I thought I'd chime in with an alternative way of doing what you are doing that is considered best practice: using Tasks. I am assuming that since you are using VS 2013 that you are targeting .NET 4.5 so you also have the async'/awaitkeywords available to you. With your current little example app, you are going to run into trouble if you try to update your UI fromdoSomething1()ordoSomething2()` because only the UI thread can modify UI controls and those methods are running on different threads.

I'd suggest instead doing something like this:

//notice the async keywords in the method declarations
private async void Threads_Button_Click_1(object sender, RoutedEventArgs e)
{
    List<Task> tasks = new List<Task>();
   tasks.Add(doSomething1());
   tasks.Add(doSomething2());
   //this will wait until both doSomething1() and doSomething2() are done in a non-blocking fashion
    await Task.WhenAll(tasks);
}
private async Task doSomething1()
{
   //you can now update UI controls here
   Console.WriteLine("Starting doSomething1");
   await Task.Delay(3000);
   Console.WriteLine("Finishing doSomething1");
}
private async Task doSomething2()
{
   //you can now update UI controls here
   Console.WriteLine("Starting doSomething2");
   await Task.Delay(6000);
   Console.WriteLine("Finishing doSomething2");
}

This is obviously much different than what you have right now, but (other users, please correct me if you have a quibble with this statement), with "modern" .NET, you really shouldn't need to spin up your own threads in a WPF application like this. This again assumes you are targeting .NET 4.5, which, by default, VS 2013 will do (to be more pedantic, it would be 4.5.1 but that is immaterial in this context).

If you are interested in using async/await instead, I'd suggest reading up on it, perhaps by starting with the helpful FAQ on the Parallel Programming blog on MSDN and/or with Stephen Cleary's intro blog post.

Upvotes: 2

Stormenet
Stormenet

Reputation: 26468

They are both the same, what you see there happening is syntax sugar called Delegate Inference.

Delegate inference allows you to make a direct assignment of a method name to a delegate variable, without wrapping it first with a delegate object.

In simple words, the compiler sees that the doSomething1 method matches a ThreadStart Delegate so just creates one for you. It knows it should match the ThreadStart because that's in one of the constructor's parameters.

For more possibilities (with lambdas etc...) see this blog.

Upvotes: 5

Related Questions