Multi-threaded Winforms Conventions for Main() I'm trying to find a good pattern for new applications (and for refactoring old ones).

Maybe it's just me, but I dislike spawning my main logic thread from inside my main form thread (so far I always have 2+ threads in my apps and beefy hardware, also .NET 4.5).  I feel it conflicts with the separation of concerns principle.

So is this a good pattern?

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading.Tasks;

namespace MyApp
{
    static class Program
    {
        /// &lt;summary&gt;
        /// The main entry point for the application.
        /// &lt;/summary&gt;
        [STAThread]
        static void Main()
        {
            try
            {
                // Prevent multiple instances of the application from opening
                using (new SingleGlobalInstance(1000))
                {
                    // Run Main Logic/Sequence Task
                    Task.Factory.StartNew(() =&gt;
                        {
                            new MainTask()
                                .Run();
                        });

                    // Display GUI
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new MainForm());    // Blocks until Form Closes
                }
            }
            catch (TimeoutException)
            {
                MessageBox.Show("An instance of the application is already open.");
            }
            catch (Exception ex)
            {
                // Log Error
                // ... log to file...

                // Display Error to User
                MessageBox.Show(ex.Message);
            }
        }
    }
}


MainTask.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace MyApp
{
    public class MainTask
    {
        // Do Work
        public void Run()
        {
            Console.WriteLine("MainTask - Running");
            Thread.Sleep(10000);
        }

        // Constructor
        public MainTask()
        {
            Console.WriteLine("MainTask - Constructed");
        }

        //// Destructor
        //~MainTask()
        //{
        //    // Destructor defined for purposes of debugging
        //    Console.WriteLine("MainTask - Destructed");
        //}
    }
}


MainForm

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MyApp
{
    public partial class MainForm : Form
    {
        // Constructor
        public MainForm()
        {
            InitializeComponent();
        }
    }
}
I would second Steven Doggart's comment about it being pointless to spawn a thread that does nothing.

To address your separation of concerns issue, though: If you are using one of a number of design patterns for your UI (e.g., MVC, MVVM, MVP, etc.), your MainForm class will merely be binding to one or more data objects and raising events from the user.  The real work and asynchrony will be done in another class.

For example, in the MVP pattern, you might have MainForm, MainPresenter, and MainViewModel.


MainForm binds various controls to properties exposed by MainViewModel
MainViewModel implements INotifyPropertyChanged and raises PropertyChangedEvents when those properties change.
MainForm updates those properties as the result of users manipulating those controls.
MainPresenter responds to events raised by MainForm and updates MainViewModel properties as well, causing MainForm to respond through the PropertyChangedEvents


It is then up to MainPresenter (or more appropriately, other classes MainPresenter uses) to figure out how to handle threading.  MainForm itself never has to know or care that you are using separate threads.