[C#] Visual 2005 Beta 1 & Thread safe operation

Résolu
scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017 - 9 nov. 2004 à 02:56
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 - 13 nov. 2006 à 18:29
Actuellement en train de tester la compatiblité de mes appli sur .NET 2005, je rencontre un petit problème d'accès entre threads et dont je ne sais pas si cela vient plus du codage que du type d'accès.

En gros, G un thread principal (cad celui de mon appli qui contient une RichTextBox. Maintenant, j'ai un autre thread qui mouiline dans un coin et qui doit rajouter du text dans l'edit.

Si je met le code dans le 2nd thread, meme le fait de lire la longueur du texte de la RichEdit me fait peter une Exception de type operation entre thread blah blah.

Quelle est donc la meilleure solution ?

----------------------------
C++ forever
C# amateur

13 réponses

Xya Messages postés 103 Date d'inscription lundi 8 juillet 2002 Statut Membre Dernière intervention 24 novembre 2005
12 nov. 2004 à 20:09
[font=Tahoma]
Je crois que tu oublies de passer tes arguments à DoPresentOnMainThread:
/font
 private void Runtime()
{
    this.richTextBox1.Invoke(new PresentHandler(this.DoPresentOnMainThread));
}


[font=Tahoma]
devrait être:
/font

private void Runtime()
{
    object[] args = new object[] {this.richTextBox1, "Main Thread : line 0" };
    this.richTextBox1.Invoke(new PresentHandler(this.DoPresentOnMainThread), args);
}
3
cs_ousta Messages postés 95 Date d'inscription mardi 15 juin 2004 Statut Membre Dernière intervention 2 juin 2007
9 nov. 2004 à 12:13
Bonjour je connais pas ton code mais peut etre que tes threads accedent en meme temps a une meme variable, essaye peut etre avec lock().
0
scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017
10 nov. 2004 à 01:21
Le lock() ne change rien sur .NET 2005

voici le code :

using System;
using System.Threading;
using System.Windows.Forms;

namespace QuickSample
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private RichTextBox richTextBox1;
private System.Threading.Thread myEngineThread;
private System.ComponentModel.IContainer m_components = null;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

// TODO: Add any constructor code after InitializeComponent call
WriteToOutput(richTextBox1, "Main Thread : line 0");

//myEngineThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(this.Runtime));
myEngineThread = new System.Threading.Thread (new ThreadStart(this.Runtime));
this.myEngineThread.Start();

}

public void WriteToOutput(RichTextBox _oDst, string _szText)
{
_oDst.AppendText(_szText);
}

static readonly object countLock = new object();
private void Runtime()
{
// Illegal cross thread operation
lock (countLock)
{
richTextBox1.AppendText("toto");
}
//
// OU
//
// Parameter count mismatch
//this.richTextBox1.Invoke(new PresentHandler(this.DoPresentOnMainThread));
}

private delegate void PresentHandler(RichTextBox _oDst, string _szText);
private void DoPresentOnMainThread(RichTextBox _oDst, string _szText)
{
_oDst.AppendText(_szText);
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (m_components != null)
{
m_components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(28, 37);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(206, 176);
this.richTextBox1.TabIndex = 0;
this.richTextBox1.Text = "";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.richTextBox1);
this.Name = "Form1";
this.Text = "MyDialog";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
}
0
scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017
16 nov. 2004 à 00:35
rien changé :-(

----------------------------
C++ forever
C# amateur
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Xya Messages postés 103 Date d'inscription lundi 8 juillet 2002 Statut Membre Dernière intervention 24 novembre 2005
16 nov. 2004 à 13:41
Tu as toujours l'exception TargetParameterCountException? Parce qu'avec les modifications que j'ai faites ton code tourne sans problème.
0
scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017
16 nov. 2004 à 23:18
Heu vi ca marche mais faut pas mettre de Break Point sur le Invoke, c'est ca qui fait bacher.
Mais pk cela ? alors la aucune idee

----------------------------
C++ forever
C# amateur
0
Xya Messages postés 103 Date d'inscription lundi 8 juillet 2002 Statut Membre Dernière intervention 24 novembre 2005
17 nov. 2004 à 13:25
Je crois que c'est un bug de VS Beta 1, si tu poses un breakpoint sur Invoke et que tu avance à la ligne suivant ca passe, mais si tu inspecte un contrôle de ta feuille (comme ici richTextBox1), il va appeller ToString du contrôle, ce qui va lancer une exception de synchronisation que tu te récupère après l'appel à Invoke.
Je l'ai posté dans le MSDN Feedback Center.
0
cs_xmo Messages postés 9 Date d'inscription jeudi 27 janvier 2005 Statut Membre Dernière intervention 31 décembre 2005
27 janv. 2005 à 15:23
Salut,
Est ce que ton souci d'acces entre threads a été résolu.
J'ai eu à un moment un souci similaire que j'ai resolu.
exemple de code:


//Dans vs2005 pour pas avoir le message d’erreur « Illegal cross thread operation »<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />





/* Dans le Thread principal */


//Declaration du contrôle


PictureBox grWatch = new PictureBox() ;


//initialisations des proprietes du contrôle





//Propriete du UserControl qui donne l’acces à Picture.Graphics


private Graphics WatchGraphics


{


get { return (Graphics)Invoke(new GetWatchGraphicsDelegate(GetWatchGraphics)); }


}


//Delegate et sa fonction associée


//Ils permettent d’acceder au menbres d’un contrôle à partir d’un thread qui ne l’a pas créer


private delegate Graphics GetWatchGraphicsDelegate();


private Graphics GetWatchGraphics()


{


return grWatch.CreateGraphics();


}





/* Dans le Thread du timer */


//Au moment de l’acces


bg = bgc.Allocate( WatchGraphics , new Rectangle(0, 0, WatchGraphicsWidth, WatchGraphicsHeight));

[mailto:mox@hotmail.fr mox@hotmail.fr]
0
cs_olecossois Messages postés 18 Date d'inscription jeudi 13 février 2003 Statut Membre Dernière intervention 12 mars 2008
8 nov. 2006 à 11:59
Y'a mieux, mais avec beaucoup moins de sécurité pour le problème Illegal Cross Threading

Ajouté ça dans le Load : Control.CheckForIllegalCrossThreadCalls=false

Ca enlève la securité sur le frameword 2.0

Bien cordialement

Olivier
0
scoubidou944 Messages postés 714 Date d'inscription mardi 22 avril 2003 Statut Membre Dernière intervention 19 janvier 2017
8 nov. 2006 à 12:11
oui je connaissais, c'est pour du portage de code façon porscasse. A eviter au possible.

----------------------------
C++ forever
C# amateur
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
10 nov. 2006 à 19:38
Salut,

olecossois >
Ce qui a pour effet de masquer le problème et non le résoudre...
Le mieux est donc naturellement de passer par ce qui est décrit par exemple dans ce tuto : OPÉRATIONS CROSS THREADS - UTILISATION DES DELEGATIONS SYNCHRONES / ASYNCHRONES

/*
coq
MVP Visual C#
CoqBlog
*/
0
cs_olecossois Messages postés 18 Date d'inscription jeudi 13 février 2003 Statut Membre Dernière intervention 12 mars 2008
13 nov. 2006 à 09:51
Je suis complètement d'accord, que ça ne résoud pas le problème, ça ne fait que le contourner, évidemment, le mieux étant de le résoudre, mais pour une action rapide, pour vérification, ça peut être pratique

Olivier
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
13 nov. 2006 à 18:29
Oui , c'était surtout pour être sûr que personne ne prenne ça comme solution viable :-)

/*
coq
MVP Visual C#
CoqBlog
*/
0
Rejoignez-nous