2016-08-25 7 views
0

ベストタイトルであることが分かりません。スプラッシュスクリーン、スレッディング、競合条件

スレッドに問題があります。 Application_Startup私は静的なヘルパークラスの助けを借りて簡単なスプラッシュスクリーンウィンドウを開く新しいスレッドを開始します。 Application_Startupには、ユーザーがログインしているかどうかをチェックし、まだサインインしていない場合はログインウィンドウが開きます。この時点で、ログインウィンドウが表示された場合、スプラッシュ画面はcloseになりますが、表示されません。

​​

我々はcheck方法でelse条件を打ったときに物事は失敗し始めます。まず、SplashScreenHelper.Close();にブレークポイントを設定し、Splashのインスタンスがnullであることが判明したため、SplashウィンドウからのCloseは発生しません(下記のクラスを参照)。面白いのは、正しくインスタンス化され、スプラッシュ画面のウィンドウが表示された場合、どのようにnullになることができるかということです。ここで

のアイデアを得るために SplashScreenHelperクラスです:

class SplashScreenHelper 
{ 
     public static Splash SplashScreen { get; set; } 

     public static void Show() 
     { 
      if (SplashScreen != null) 
      { 
       SplashScreen.Show(); 
      }  
     } 

     public static void Close() 
     { 
      if (SplashScreen == null) return; 
      if (!SplashScreen.Dispatcher.CheckAccess()) 
      { 
       SplashScreen.Dispatcher.Invoke(DispatcherPriority.Normal, 
        new Action(delegate() 
        { 
         System.Windows.Threading.Dispatcher.CurrentDispatcher.InvokeShutdown(); 
         SplashScreen.Close(); 
        })); 
      } 
      else 
      { 
       SplashScreen.Close(); 
      } 
     } 

     public static void ShowText(string text) 
     { 
      if (SplashScreen == null) return; 

      if (!SplashScreen.Dispatcher.CheckAccess()) 
      { 
       SplashScreen.Dispatcher.Invoke(
        DispatcherPriority.Normal, 

        new Action(delegate() 
        { 
((SplashScreenViewModel)SplashScreen.DataContext).SplashScreenText = text; 
        } 
       )); 
      } 
      else 
      { 
       ((SplashScreenViewModel)SplashScreen.DataContext).SplashScreenText = text; 
      } 

     } 
    } 

私たちは、私は2つの窓が持っているelseというヒット:スプラッシュウィンドウが閉じられているはずですが、スプラッシュ画面ウィンドウとログインウィンドウを、それスプラッシュスクリーンのインスタンスがnullで、これは何が起こるかわからないからです。

どういうわけか、checkメソッドが起動する前に起動し、ログインウィンドウを開き、elseステートメントにヒットし、スプラッシュスクリーンを閉じようとしますが、そのスプラッシュスクリーンスレッドは決して起動せず、インスタンス化しませんでした。 の場合、スレッドは最後にスプラッシュ画面をインスタンス化します。

+0

あなたのスプラッシュ画面は何ですか?そうでない場合は、組み込みのメカニズムを使用して頭痛を避けるのはなぜですか? https://msdn.microsoft.com/en-us/library/cc656886(v=vs.110).aspx – Will

+0

これは常にユーザーに情報を表示します。モジュールロードの進捗バーとそれには著作権表示が含まれています。一番上にパブリッシュン版。 – Dimitri

答えて

0

checkを呼び出す前に、2番目のスレッドのコードの最初の部分が実行されていることを確認する必要があります。

ManualResetEventがこれに該当します!

using (ManualResetEvent mre = new ManualResetEvent(false)) 
{ 
    Thread thread = new Thread(new ThreadStart(
     delegate() 
     { 
      SplashScreenHelper.SplashScreen = new Splash() 
      // this works. the splash screen opens 
      SplashScreenHelper.Show(); 
      mre.Set(); // signal that we are done setting up the splash screen 
      System.Windows.Threading.Dispatcher.Run(); 
     } 
    )); 
    thread.SetApartmentState(ApartmentState.STA); 
    thread.IsBackground = true; 
    thread.Start(); 

    mre.WaitOne(); // wait until the signal is received 
} 

check(); // now we can safely call check() 
+0

これを試してみます – Dimitri

関連する問題