Domanda

Io sto usando una schermata iniziale da Qui . Mi piace come sia semplice. Ma il problema con esso è che la schermata iniziale non va via fino a quando clicco su di esso. Quando viene eseguito all'interno dell'IDE funziona benissimo. Qualche idea? Mi piacerebbe Allego il codice qui, ma la sua non inserendo correttamente per qualche motivo.

private System.Windows.Forms.Timer timer1;
//private Splash sp=null;

public Form1()
{
    InitializeComponent();

    Thread th = new Thread(new ThreadStart(DoSplash));
    //th.ApartmentState = ApartmentState.STA;
    //th.IsBackground=true;
    th.Start();
    Thread.Sleep(3000);
    th.Abort();
    Thread.Sleep(1000);
}

private void DoSplash()
{
    Splash sp = new Splash();
    sp.ShowDialog();
}

private void timer1_Tick(object sender, System.EventArgs e)
{
//      sp.Close();
}
È stato utile?

Soluzione

Prima di tutto, il modo in cui la schermata iniziale in quella pagina è fatto, utilizzando Thread.Abort , è non il modo giusto di fare le cose.

Discussione .Abort , a meno che non si è in procinto di chiudere il AppDomain il filo vive.

Vorrei ribadire che per dare enfasi. L'unica volta che si dovrebbe chiamare Thread.Abort è quando si sa abbastanza di Thread.Abort e come si comporta per sapere che non si dovrebbe mai chiamarlo.

Date un'occhiata a quest'altra domanda su StackOverflow: splash screen Multi-Threaded in C # ? .


Se si desidera mantenere la soluzione esistente, una possibile via migliore sarebbe quella di rilasciare un timer nella forma schermata iniziale, impostare il timer per il tempo che si desidera visualizzare la schermata iniziale di rimanere sullo schermo, e chiamare primo nel suo gestore di eventi Tick.

Nella stessa sede, vorrei semplicemente sparare quel filo originale, e rimuovere le altre linee.

In altre parole, a partire dal primo blocco di codice su quella pagina, vorrei tenere queste due righe:

Thread th = new Thread(new ThreadStart(DoSplash));
th.Start();

Coppia che, con quel timer sul modulo che rende l'auto-chiusura modulo, e siete in maniera forma migliore che cercare di fare i conti con Thread.Abort.

Il che non si dovrebbe chiamare.

Altri suggerimenti

Il DoSplash dovrebbe probabilmente chiamare sp.Show() invece di sp.ShowDialog()

Ma chiamando sonno (x000) formano il tuo thread principale per mostrare una schermata iniziale non è molto efficiente, e Thread.Abort () dovrebbe essere riservato per l'uso migliore.

Un approccio migliore è quello di chiudere lo SplashForm con un timer e impostare un ritardo minimo. All'avvio è possibile mostrare () e Update () lo SplahForm e continuare a caricare roba. L'evento del timer non si attiverà fino a quando il MainForm è terminato l'inizializzazione ed entra nel EventLoop. Non ci sono discussioni necessario, e il MainForm non deve essere coinvolto sia.

Solo per darvi gli ingredienti principali di uno SplashForm MessageLoop guidato:

public partial class SplashForm : Form
{
    //  default stuff

    public static void Splash()
    {
        var s = new SplashForm();
        s.Show();
        s.Update();// force paint
    }

    private void SplashForm_Load(object sender, EventArgs e)
    {
        Timer t = new Timer();
        t.Interval = 1; // wait for EventLoop
        t.Tick += GoAway;
        t.Enabled = true;
    }

    private void GoAway(object sender, EventArgs e)
    {
        this.Close();
    }
}

e poi, in Program.cs,

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SplashForm.Splash();
Application.Run(new MainForm());

Questo è un brutto implementazione. Si dovrebbe verificare questo SO filo . Che descrive come utilizzare lo spazio dei nomi VisualBasic.NET da C # e il OnCreateSplashScreen metodo per fare un'implementazione splash screen molto più pulito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top