Toute solution à l'exception d'opération illégale Cross Thread?

Lorsque vous liez des données en C#, le thread qui modifie les données provoque également le contrôle changer. Mais si ce thread n'est pas celui sur lequel le contrôle a été créé, vous obtiendrez une exception d'opération de thread croisé illégale.

Est-il un moyen d'empêcher cela?

0

5 Réponses

Vous devriez être capable de faire quelque chose comme:

if (control.InvokeRequired)
{
    control.Invoke(delegateWithMyCode);
}
else
{
    delegateWithMyCode();
}

InvokeRequired est une propriété sur Controls pour voir si vous êtes sur le bon thread, puis Invoke appelle le délégué sur le bon thread.

MISE À JOUR: En fait, lors de mon dernier travail, nous avons fait quelque chose comme ceci:

private void SomeEventHandler(Object someParam)
{
    if (this.InvokeRequired)
    {
        this.Invoke(new SomeEventHandlerDelegate(SomeEventHandler), someParam);
    }

    // Regular handling code
}

ce qui supprime le besoin d'un autre bloc et renforce le code.

0
ajouté

Comme je n'ai pas de scénario à tester, je ne peux pas garantir cette solution, mais il me semble qu'un scénario similaire à celui utilisé pour mettre à jour les barres de progression dans différents threads (utiliser un délégué) conviendrait ici.

public delegate void DataBindDelegate();
public DataBindDelegate BindData = new DataBindDelegate(DoDataBind);

public void DoDataBind()
{
    DataBind();
}

Si la liaison de données doit être effectuée par un thread particulier, laissez ce thread faire le travail!

0
ajouté

Si l'appel de thread est "illégal" (l'appel DataBind affecte les contrôles qui n'ont pas été créés dans le thread à partir duquel il est appelé), vous devez créer un délégué de sorte que même si la décision / préparation de DataBind n'est pas le thread de création de contrôle, toute modification résultante de ceux-ci (ie DataBind ()) sera.

Vous appelez mon code du thread de travail comme suit:

this.BindData.Invoke();

Cela entraînerait alors le thread d'origine à faire la liaison, qui (en supposant que c'est le thread qui a créé les contrôles) devrait fonctionner.

0
ajouté

Si la modification des données ne prend pas trop de temps (c'est-à-dire si l'objectif principal du thread d'arrière-plan n'est pas la modification des données), essayez de déplacer la section qui modifie les données vers un délégué et Invoquez ce délégué.

Si le gros travail est sur les données, vous devrez probablement créer une copie profonde de ces données pour passer au thread d'arrière-plan, ce qui enverra à nouveau les données traitées au thread de l'interface utilisateur via Invoke.

Vous n'aurez qu'à déplacer le code qui modifie les données dans la fonction déléguée (car le changement de données est ce qui déclenche la mise à jour du contrôle). À part ça, vous ne devriez pas avoir à écrire quoi que ce soit de plus.

0
ajouté

Dans wpf et Silverlight, l'infrastructure de liaison prend en charge le basculement vers le thread d'interface utilisateur.

0
ajouté