Bonjour,

Voici un petit descriptif de mon problème :
J'ai un datagrid rempli des lignes, par exemple des commandes.
Lorsque je fais un double click, j'ouvre un formulaire reprenant les détails de cette commande. Jusque là tout va bien.

Le formulaire de détail de commande contient beaucoup de combobox. Ces combos sont remplies et bindés avec des données venant d'une db.
Pour rendre l'ouverture de ce formulaire plus rapide, j'ai réalisé le chargement et le binding de ces combo via un autre thread et j'ai fait attention à bien mettre à jour l'interface. Jusque là tout va encore très bien.

Je rencontre néanmoins un problème avec des utilisateurs trop pressés : ils ouvrent le formulaire de détail par erreur et le referment aussitôt sans que le thread de chargement des combos n'aie eut le temps de se terminer : résultat une belle erreur du type :

An unhandled exception of type 'System.InvalidOperationException' occurred in system.windows.forms.dll
Additional information: Impossible d'appeler Invoke ou InvokeAsync sur un contrôle tant que le handle de fenêtre n'a pas été créé."

Ce qui est logique vu que le formulaire est fermé et que le thread essaie de le mettre à jour.

Comment éviter cette erreur ?

J'ai mis dans l'event form_closing, l'instruction suivante :
If _updateThread.IsAlive Then _updateThread.Abort()

Cela est-il propre ?

Voici mon code :

Code vb : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
   Private _updateThread As Thread
    Private _updateThreadStart As New ThreadStart(AddressOf LoadData)
    Private _dataBindToCombo As New MethodInvoker(AddressOf Me.DataBindToCombo)
 
#Region "Form item formatting"
 
    Private Sub ItemDetail_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        Me.Cursor = Cursors.WaitCursor
 
        StartLoadCombos()
 
        ' Je fais pleins d'autres choses....
 
        bChargement = False
 
    End Sub
 
#End Region
 
#Region "Thread functions to load the combos on a thread"
 
    Sub StartLoadCombos()
 
        Try
            _updateThread = New Thread(_updateThreadStart)
            With _updateThread
                .IsBackground = True
                .Name = "ChargementComboThread"
                .Start()
            End With
        Catch ex As Exception
            'ShowError(ex)
            MessageBox.Show(ex.ToString)
        End Try
 
    End Sub
 
    Sub LoadData()
 
        ' Load the combos on a thread
        _dd = _dal_combo.GetDropDowns()
        Me.BeginInvoke(_dataBindToCombo)
 
    End Sub
 
    Sub DataBindToCombo()
 
        _statuts = _dd(0).ItemLocalisationStatuts
 
        With Me.cboStatut
            .DataSource = _statuts
            .DisplayMember = "Statut"
            .ValueMember = "ID_statut"
            '.DataBindings.Add("Value", _localisationsDS.Tables(0), "ID_statut")
        End With
 
        'même code repété pour les autres combos
 
        bChargementCombos = False
 
    End Sub
 
#End Region

Merci pour vos conseils