2012-08-04 230 views
3

可能重複:
C# Splash Screen ProblemUI線程被阻塞

我是新來的C#,我工作了軟件啓動時運行啓動屏幕上。我在啓動屏幕類中檢查數據庫的功能。我正在使用線程調用函數

 sc = new splashScreen(); 

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

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

問題是UI被阻塞,直到線程處於活動狀態。並在最後它給我數據庫連接狀態消息。 這是我的代碼。我已經使用checkDLLThread.join(),但它也不起作用。

+0

你爲什麼不只是刪除的睡眠?這是什麼阻止用戶界面。 – usr 2012-08-04 10:32:38

+1

我已經嘗試通過刪除睡眠,循環然後阻止用戶界面 – greatmajestics 2012-08-04 10:37:32

+0

好吧,當然也刪除循環;-)解除屏蔽UI線程需要從您的事件處理程序返回。 – usr 2012-08-04 10:38:44

回答

1

splashscreen僅僅是一個圖像,當您的應用程序加載時可以「充滿」用戶。使用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 
    } 

而且,我覺得BackGroundworker類是這樣的事情更好,如果你不想打擾用戶界面。

+0

我正在使用VS 2005,在那裏我可以找到這個東西 – greatmajestics 2012-08-04 10:38:05

+0

我假設你正在使用WPF。你使用Windows窗體嗎? – AmazingDreams 2012-08-04 10:38:55

+0

我認爲將代碼放入Application_Startup也會阻止(爲什麼不呢?想不出任何理由)。 – usr 2012-08-04 10:39:27

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 

訣竅是讓線程顯示消息,等一旦完成。不要等待線程,讓線程自己做。

您的線程可能需要使用Invoke函數來訪問UI。如果你想在後臺線程上執行異步工作,你可能不會閱讀這些內容,因爲沒有辦法繞過它。

1

下面的代碼在單獨的線程上啓動一個「啓動畫面」,而您的應用程序(在我的示例中,它被稱爲MainForm())加載或初始化。首先在你的「main()」方法中(在你的program.cs文件中,除非你重命名了它),你應該顯示你的啓動畫面。這將是一個WinForm或WPF表單,您希望在啓動時向用戶顯示。這是主要推出()如下:

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

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

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

在你的閃屏的代碼,你需要像下面這樣:

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線程獲取信息,或者以純粹的審美性質工作。爲了完成並關閉閃屏下來的時候你的應用程序已被初始化你把默認的構造函數中以下(你可以重載的構造函數,如果你想):

上面的代碼應該是比較容易跟隨。

我希望這會有所幫助。

1

你的方法很好,但你應該同時運行。使用static fields可以輕鬆完成這項工作。相反的:

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

你應該:

  • 顯示啓動Form
  • 設置上開始被隱藏的形式,即設置Opacity0
  • 檢查不斷在變SplashForm當您的表單完全初始化時
  • Set 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; 
}