Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TPL Equivalent of Thread Class 'Splash-Type' Screen

Given the class below, to launch a splash screen on an alternate thread:

public partial class SplashForm : Form
{
    private static Thread _splashThread;
    private static SplashForm _splashForm;    

    public SplashForm()
    {
        InitializeComponent();
    }

    // Show the Splash Screen (Loading...)      
    public static void ShowSplash()    
    {        
        if (_splashThread == null)        
        {            
            // Show the form in a new thread.          
            _splashThread = new Thread(new ThreadStart(DoShowSplash));            
            _splashThread.IsBackground = true;            
            _splashThread.Start();        
        }    
    }    

    // Called by the thread.  
    private static void DoShowSplash()    
    {        
        if (_splashForm == null)            
            _splashForm = new SplashForm();       

        // Create a new message pump on this thread (started from ShowSplash).       
        Application.Run(_splashForm);
    }    

    // Close the splash (Loading...) screen.
    public static void CloseSplash()    
    {        
        // Need to call on the thread that launched this splash.      
        if (_splashForm.InvokeRequired)            
            _splashForm.Invoke(new MethodInvoker(CloseSplash));        
        else            
            Application.ExitThread();    
    }
}

This is called and closed with the following respective commands

SplashForm.ShowSplash();
SplashForm.CloseSplash();

Fine.

I am not exactly new to the TPL, of course we can show the form on another thread using something as simple as:

Task task = Task.Factory.StartNew(() => 
{
    SomeForm someForm = new SomeForm();
    someForm.ShowDialog();
};

My issue is closing this SomeForm down when you are ready. There must be a better way than creating a public static method in the SomeForm class like

private static SomeForm _someForm;
public static void CloseSomeForm()    
{        
    if (_someForm.InvokeRequired)            
        _someForm.Invoke(new MethodInvoker(CloseSomeForm));        
}

My question is, what is the best way to do the same thing as shown using the SplashForm class above using the Task Parrallel Library (TPL)? Specifically, the best way to close the form invoked on another thread from the UI.

like image 210
MoonKnight Avatar asked Mar 08 '13 16:03

MoonKnight


People also ask

How are threads different from TPL?

Compared to the classic threading model in . NET, Task Parallel Library minimizes the complexity of using threads and provides an abstraction through a set of APIs that help developers focus more on the application program instead of focusing on how the threads will be provisioned.

What is TPL in .NET core?

The Task Parallel Library (TPL) is a set of public types and APIs in the System. Threading and System. Threading. Tasks namespaces. The purpose of the TPL is to make developers more productive by simplifying the process of adding parallelism and concurrency to applications.

What is TLP C#?

Task Parallel Library (TPL), basically provides a higher level of abstraction. Fundamentally, it boils down to a “task” which is equivalent to a thread except that it is more lightweight and comes without the overhead of creating an OS thread.


1 Answers

Your question does not seem to be so much about a difference between Thread and Task because what you want is to get rid of the "dirty" static state. I suggest you encapsulate it into a class:

class SplashController
{
    public void Run() {
        _someForm = new SomeForm();
        someForm.ShowDialog();
    }

    private SomeForm _someForm;
    public void CloseSomeForm()    
    {        
        if (_someForm.InvokeRequired)            
            _someForm.Invoke(new MethodInvoker(CloseSomeForm));        
    }
}

You can call Run using whatever threading mechanism you like. CloseSomeForm does not use threading so it is independent of this problem.

You can now store a reference to an instance of SplashController wherever you like. In local variables or indeed in a static variable. The latter makes sense because there is exactly one splash screen.

Because the static state is now well encapsulated I don't see any problem with it being statically held.

like image 177
usr Avatar answered Oct 30 '22 11:10

usr