Je travaille sur une application multithread qui doit mettre à jour un contrôle Winforms à mesure qu'il progresse (un DataGridView). Afin d'empêcher l'accès multiple à la même ressource partagée, j'ai commencé avec la structure de verrouillage suivante:Utilisation de Control.Invoke() à la place du verrou (Control)
if (DGV.Columns.Count >= DesiredColumnCount) return;
lock(DGV)
{
while (DGV.Columns.Count < DesiredColumnCount)
{
DGV.Columns.Add(newColumn);
}
}
Je me suis alors rendu compte que, depuis le DGV a été créé sur le thread d'interface utilisateur, il doit être .Invoke()
« d . Cela change le code à:
if (DGV.Columns.Count >= DesiredColumnCount) return;
lock(DGV)
{
DGV.Invoke(new MethodInvoker(() =>
{
while (DGV.Columns.Count < DesiredColumnCount)
{
DGV.Columns.Add(newColumn);
}
}
}
Ma question est: Est-ce que ce n'est pas redondant? le lock
bloquera le thread de travail jusqu'à ce qu'il ait un accès exclusif à DGV
, et le Invoke()
bloquera le thread de travail jusqu'à ce que le thread de l'interface utilisateur puisse prendre la demande d'invocation et exécuter le code. Je ne peux pas juste obtenir en utilisant seulement le Invoke()
?
(Telle est la question principale. Bien sûr, s'il y a d'autres péchés multithreading dans le code ci-dessus, s'il vous plaît un commentaire)
Qu'est-ce que vous utilisez pour un "thread de travail"? –
Vous ne devez jamais bloquer le thread d'interface utilisateur. Cela vaut pour Lock ainsi que Control.Invoke. Vous devriez vous débarrasser du verrou et changer Invoke en BeginInvoke. –
@PeterRitchie Je ne me souviens pas exactement de ce qui a commencé le fil. C'était probablement 'new Thread(). Start()' ou 'System.Threading.Timer.Elapsed'. Ce code n'aurait pas bloqué le thread d'interface utilisateur, il aurait bloqué le travailleur. BeginInvoke ne peut pas être substitué aveuglément à Invoke car il ne bloque pas l'appelant: je devrais mettre en file d'attente les invocations pour m'assurer qu'elles ne se chevauchent pas pour être exécutées dans le mauvais ordre. Cela peut augmenter les performances en réduisant le temps passé à bloquer les threads de travail, mais c'est un ancien projet à ce jour. – Nathan