2012-01-31 3 views
0

Je montre un formulaire en attente (en disant "Please wait ...") sur un thread différent quand il y a du code à long terme sous certaines formes (par exemple, pendant le chargement des données). Je montre la forme comme ceci:Erreur Control.Invoke: handle pas encore créé

m_PopProcessingThread = New Thread(New ThreadStart(
    Sub() 
     m_PopProcessingForm = New WaitingForm(m_Message) 
     Application.Run(m_PopProcessingForm) 
    End Sub)) 
m_PopProcessingThread.Name = "Pop Processing Thread" 
m_PopProcessingThread.SetApartmentState(ApartmentState.STA) 
m_PopProcessingThread.Start() 

Puis-je cacher comme ceci:

While m_PopProcessingForm Is Nothing OrElse Not m_PopProcessingForm.IsHandleCreated 
    Threading.Thread.Sleep(20) 'Wait a bit for the form to be created 
End While 
' Dispose of the pop processing form (by disposing of this form, thread is also exited) 
m_PopProcessingForm.Invoke(Sub() 
           m_PopProcessingForm.Dispose() 
          End Sub) 

Ce code fonctionne très bien, mais je viens de recevoir un rapport de bogue d'un client:

Exception Type : System.InvalidOperationException 
Invoke or BeginInvoke cannot be called on a control until the window handle has been created. 
    at System.Windows.Forms.Control.WaitForWaitHandle(WaitHandle waitHandle) 
    at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous) 
    at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args) 
    at System.Windows.Forms.Control.Invoke(Delegate method) 

La trace de la pile pointe vers la partie du code où je masque le formulaire. Comment le handle n'a-t-il pas pu être créé, juste avant l'appel Invoke, je boucle jusqu'à ce que le handle soit créé? Merci de votre aide.

+0

Utilisez un BackgroundWork et/ou une Tâche, ils sont conçus exactement dans ce but. –

+0

Je sais que c'est un peu à l'envers, habituellement la tâche devrait être dans un autre thread, au lieu d'un formulaire en attente. Mais compte tenu du code actuel fonctionne 99,999% du temps, je préfère le réparer que de changer tout mon code. –

Répondre

2

Le formulaire a probablement été fermé après votre vérification IsHandleCreated mais avant que Dispose ne soit invoqué. Peut-être que l'utilisateur a cliqué sur [x] ou appuyé sur Ctrl-F4 sur le formulaire.

+0

Ce serait surprenant, il n'y a pas de bouton X sur ce formulaire, et le formulaire ne reste pas ouvert longtemps. –

+0

Je suppose que ce bug est peut-être arrivé en appuyant sur Alt-F4, mais il serait très surprenant que le formulaire soit fermé entre les instructions IsHandleCreated et Invoke, étant donné qu'ils se suivent. –

+0

Vous m'avez fait réaliser qu'il pourrait y avoir une boucle infinie si l'utilisateur appuie sur Alt-F4, alors merci pour cela! –

Questions connexes