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

解锁 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。您可能不想阅读这方面的内容,因为如果您想在后台线程上进行异步工作,就无法绕过它。

于 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
  • 设置Opacity1线程完成时。即变量变化

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 回答
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 回答