3

重複の可能性:
C#スプラッシュ画面の問題

私はc#を初めて使用し、ソフトウェアの起動時に実行されるスプラッシュ画面に取り組んでいます。データベースをチェックするスプラッシュ画面クラスの関数があります。スレッドを使用して関数を呼び出しています

        sc = new splashScreen();

        checkDLLThread = new Thread(new ThreadStart(sc.checkDLLS).BeginInvoke);
        checkDLLThread.Start();

        while (checkDLLThread.IsAlive)
        {
            Thread.Sleep(200);
        }

問題は、スレッドがアライブになるまでUIがブロックされることです。そして最後に、データベース接続ステータスメッセージが表示されます。これが私のコードです。checkDLLThread.join()を使用しましたが、機能しません。

4

4 に答える 4

1

スプラッシュスクリーンは、アプリの読み込み中にユーザーを「楽しませる」ための単なる画像です。app_loadメソッドを使用して、起動時にコードを実行します。

そのように:(app.xamlおよびapp.xaml.cs内)

    <Application /some references to stuff/ Startup="Application_Startup" >

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        // your startupcode
    }

また、UIを気にしたくない場合は、 BackGroundworkerクラスの方がこのような場合に適していると思います。

于 2012-08-04T10:33:11.953 に答える
1

UIスレッドのブロックを解除するには、イベントハンドラーから戻る必要があります。それを行う以外に方法はありません。ここにいくつかの擬似コードがあります:

OnStartup:
 Start new Thread
 Disable UI
 Show Splash Sceen
 Return!

Thread:
 Check Database
 if (not ok)
  Show Message box
  Exit Application
 else
  Enable UI
  Remove Splash Screen

秘訣は、スレッドにメッセージを表示させることです。メッセージが表示されたら、メッセージを表示します。スレッドを待たずに、スレッドに任せてください。

スレッドはおそらく、UIにアクセスするためにInvoke関数を使用する必要があります。バックグラウンドスレッドで非同期作業を行いたい場合は、それを回避する方法がないため、これについては少し読みたくないかもしれません。

于 2012-08-04T10:42:36.487 に答える
1

次のコードは、アプリケーション(以下の例ではMainForm()と呼ばれます)がロードまたは初期化されている間に、別のスレッドで「スプラッシュ画面」を起動します。まず、「main()」メソッド(名前を変更していない限り、program.csファイル)でスプラッシュ画面を表示する必要があります。これは、起動時にユーザーに表示するWinFormまたはWPFフォームになります。これは、次のようにmain()から起動します。

[STAThread]
static void Main()
{
    // Splash screen, which is terminated in MainForm.       
    SplashForm.ShowSplash();

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    // Run UserCost.
    Application.Run(new MainForm());
}

SplashScreenコードには、次のようなものが必要です。

public partial class SplashForm : Form
{

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

}

これにより、別のバックグラウンドスレッドでスプラッシュフォームが起動し、メインアプリケーションのレンダリングを同時に続行できるようになります。ロードに関するメッセージを表示するには、メインUIスレッドから情報を取得するか、純粋に美的な性質で作業する必要があります。アプリケーションが初期化されたときにスプラッシュ画面を終了して閉じるには、デフォルトのコンストラクター内に以下を配置します(必要に応じてコンストラクターをオーバーロードできます)。

    public MainForm()
    {
        // ready to go, now initialise main and close the splashForm. 
        InitializeComponent();
        SplashForm.CloseSplash();
    }

上記のコードは、比較的簡単に理解できるはずです。

これがお役に立てば幸いです。

于 2012-08-04T13:18:31.250 に答える
1

あなたのアプローチは良いですが、両方を同時に実行する必要があります。の良い使い方はstatic fields簡単に仕事をすることができます。それ以外の:

    while (checkDLLThread.IsAlive)
    {
        Thread.Sleep(200);
    }

あなたがすべき:

  • スプラッシュを表示Form
  • 開始時に非表示になるようにフォームを設定します。つまりOpacity0
  • フォームが完全に初期化されたら、変数を着実に確認してくださいSplashForm
  • スレッドが完了したときにOpacity戻ります。1つまり、変数の変更

i.e.:

public Form1(){
     InitializeComponent();
     Opacity = 0;
     while(sc.IsComplete){}
     Opacity = 1;
}

そして、あなたの中には、次のようなものSplashFormがあるはずです:

internal static bool IsComplete;

internal static void CheckDLLS()
{
    //after doing some stuff
    IsComplete = true;
}
于 2012-08-04T14:14:41.930 に答える