6

以下のクラスでは、代替スレッドでスプラッシュ スクリーンを起動します。

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();    
    }
}

これは、次のそれぞれのコマンドで呼び出され、閉じられます

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

罰金。

私はTPLにまったく慣れていません。もちろん、次のような単純なものを使用して、別のスレッドでフォームを表示できます。

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

私の問題は、準備ができたらこれを閉じるSomeFormことです。のようなクラスでpublic staticメソッドを作成するよりも良い方法があるはずですSomeForm

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

私の質問は、タスク並列ライブラリ (TPL) を使用して、上記の SplashForm クラスを使用して示したのと同じことを行う最善の方法は何ですか? 具体的には、UI から別のスレッドで呼び出されたフォームを閉じる最良の方法です。

4

2 に答える 2

2

こんなことしなくていいのかもしれない

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

フォームを作成する正確なスレッド (ThreadPool スレッド) にメッセージ ループが存在する必要があるためです。しかし、私はこれをテストしていません。

これを試すことができます:

public static Task<SplashForm> ShowSplash()    
{        
    var tcs = new TaskCompletionSource<SplashForm>();

    // Show the form in a new thread.          
    _splashThread = new Thread(() =>
    {
        var splashForm = new SplashForm();       

        tcs.SetResult(_splashForm);

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

    _splashThread.IsBackground = true;            
    _splashThread.Start();        
}    

これにより、CloseSplash から static 修飾子を削除できます。

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

次のように使用できます。

var form = await SplashForm.ShowSplash();
form.CloseSplash();
于 2013-03-08T16:52:12.623 に答える