Home Page
Articoli
Tips & Tricks
News
Forum
Archivio Forum
Blogs
Sondaggi
Rss
Video
Utenti
Chi Siamo
Contattaci
Username:
Password:
Login
Registrati ora!
Recupera Password
Home Page
Stanze Forum
App. WinForms / WPF .NET
Multithreading
domenica 08 giugno 2008 - 11.12
Elenco Threads
Stanze Forum
Aggiungi ai Preferiti
Cerca nel forum
maxmax03
Profilo
| Newbie
25
messaggi | Data Invio:
dom 8 giu 2008 - 11:12
Ciao , sto diventando matto con un problema di mulltithreading.
Da una dll mi arriva la notifica dell'evento di cambiamento di stato di un servizio.
La routine che a cui arriva l'evento deve visualizzare su un TreeView lo stato dei servizi. Ma qui ho il problema si freeza la window e sul VS 2008 cosi come sul vs 2005 mi dice che devo utilizzare INVOKE o beginInvoke.
Mi potreste far capire come funziona con un esempio. Non ho capito molto bene sulle ricerce fatte su internet.
Grazie
freeteo
Profilo
| Guru
6.542
messaggi | Data Invio:
dom 8 giu 2008 - 11:52
ciao,
se vuoi fare una cosa veloce senza troppi problemi, prova ad usare questa direttiva nel form load:
Control.CheckForIllegalCrossThreadCalls = false;
così eviti che ti compaia l'errore quando un thread diverso da quello che ha creato la form va ad interagire con i controlli.
Non è il massimo dell'eleganza, ma cmq è efficace.
ciao.
Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo
maxmax03
Profilo
| Newbie
25
messaggi | Data Invio:
dom 8 giu 2008 - 14:23
Ti ringrazio ma già provato e non da il risultato che voglio. IL problema che non riesco ha capire e che sto cercando disperatamente è come un thread principale (form) ricece un evento da una dll. Dall'evento devo aggiornare una treeview ma i dati devo reperili da un metodo che è presente nella dll che scatena l'evento. Comunque garzie
freeteo
Profilo
| Guru
6.542
messaggi | Data Invio:
dom 8 giu 2008 - 14:36
>Ti ringrazio ma già provato e non da il risultato che voglio.
non si aggiorna la treeview con i valori che hai?
Forse allora il problema è qualcos'altro.
>IL problema che non riesco ha capire e che sto cercando disperatamente
>è come un thread principale (form) ricece un evento da una dll.
>Dall'evento devo aggiornare una treeview ma i dati devo reperili
>da un metodo che è presente nella dll che scatena l'evento. Comunque
la cosa è abbastanza semplice da fare, prova a postare 1po di codice su come ti sottoscrivi all'evento e come hai definito l'evento.
Grazie
ciao.
Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo
maxmax03
Profilo
| Newbie
25
messaggi | Data Invio:
dom 8 giu 2008 - 15:21
using ExeQry = Siae.Tools.ExecuteQry ;
using System;
using System.Windows.Forms;
using System.ServiceProcess ;
using System.Threading ;
namespace ClientService
{
public delegate void ChangeEventHandler(object source,int Stato);
public class PCSService
{
//private ServiceController myService = new ServiceController("System Control Service");
private Thread THService;
public event ChangeEventHandler Changed;
private delegate void IncPBDelegate();
private bool mvarThreadService = false;
private string mvarStrStatus = "" ;
private int mvarStatus = 99;
private TreeView mvarObjView= null;
private ImageList mvarObjImg= null;
/// <summary>
/// Return the service status
/// </summary>
public int Status
{
get{return mvarStatus;}
set{mvarStatus = value;}
}
/// <summary>
/// Return the service status
/// </summary>
public string DescStatus
{
get{return mvarStrStatus;}
set{mvarStrStatus = value;}
}
/// <summary>
/// Set o retrun the threadstatus for check the service
/// </summary>
public bool ThreadService
{
get{return mvarThreadService;}
set{mvarThreadService = value;}
}
public TreeView ObjView
{
get{return mvarObjView;}
set{mvarObjView = value;}
}
public ImageList ObjImg
{
get{return mvarObjImg;}
set{mvarObjImg = value;}
}
/// <summary>
///
/// </summary>
public PCSService()
{
}
/// <summary>
/// Start the thread for check service
/// </summary>
public void StartCheckService()
{
if (THService != null)
{
if (THService.IsAlive == false)
{
CreateThread();
}
else{mvarThreadService = false;}
}
else{CreateThread();}
}
/// <summary>
/// notifica la modifica dello stato
/// </summary>
protected void CreateThread()
{
mvarThreadService = true;
THService = new Thread(new ThreadStart(ServiceStatus));
THService.Name = "ServiceStatus";
THService.Start();
}
public void ChangedStatus(int Stato)
{
if (Changed != null)
Changed(this,mvarStatus);
}
public void ServiceStatus()
{
while (mvarThreadService==true)
{
ServiceController myService = new ServiceController("System Control Service");
Type MyStatoString = typeof(ServiceControllerStatus);
if (myService != null)
{
// Servizio Arrestato
if (myService.Status.Equals(System.ServiceProcess.ServiceControllerStatus.Stopped))
{
if (mvarStatus !=(Convert.ToInt16(ServiceControllerStatus.Stopped)))
{
mvarStrStatus = Enum.GetName(MyStatoString,ServiceControllerStatus.Stopped ) ;
mvarStatus = Convert.ToInt16(ServiceControllerStatus.Stopped);
ChangedStatus(Convert.ToInt16(ServiceControllerStatus.Stopped));
}
}
// Servizio Attivo
if (myService.Status.Equals(System.ServiceProcess.ServiceControllerStatus.Running))
{
if (mvarStatus != (Convert.ToInt16(ServiceControllerStatus.Running)))
{
mvarStrStatus = Enum.GetName(MyStatoString,ServiceControllerStatus.Running) ;
mvarStatus = Convert.ToInt16(ServiceControllerStatus.Running);
ChangedStatus(Convert.ToInt16(ServiceControllerStatus.Running));
}
}
// In Pausa
if (myService.Status.Equals(System.ServiceProcess.ServiceControllerStatus.Paused))
{
if (mvarStatus != (Convert.ToInt16(ServiceControllerStatus.Paused)))
{
mvarStrStatus = Enum.GetName(MyStatoString,ServiceControllerStatus.Paused) ;
mvarStatus = Convert.ToInt16(ServiceControllerStatus.Paused);
ChangedStatus(Convert.ToInt16(ServiceControllerStatus.Paused));
}
}
}
myService.Dispose();
Thread.Sleep(60000);
}
}
public void ViewStatus()
{
TreeNode tNode= new TreeNode();
ExeQry.Application ObjExecQry = new ExeQry.Application();
//mvarObjView.BeginUpdate();
mvarObjView.ImageList = mvarObjImg;
mvarObjView.ImageIndex = 5;
mvarObjView.SelectedImageIndex = 5;
mvarObjView.Nodes.Add(new TreeNode("attvio"));
//'ObjView.Nodes.Add(tNode)
//mvarObjView.EndUpdate();
ObjExecQry.XMLFileName = @"C:\temp\TempFileXml.XML";
ObjExecQry.TreeViewView =mvarObjView;
ObjExecQry.Type_View = Siae.Tools.ExecuteQry.Application.Enum_Type_View.TreeView;
ObjExecQry.ViewData.ImgList = mvarObjImg;
ObjExecQry.ViewData.set_PIconNumber(0,14);
ObjExecQry.ViewData.set_SIconNumber(0,14);
ObjExecQry.ViewData.set_PIconNumber(1,5);
ObjExecQry.ViewData.set_SIconNumber(1,5);
ObjExecQry.ViewData.set_PIconNumber(2,15);
ObjExecQry.ViewData.set_SIconNumber(2,1);
//'ExeQry.ViewData.ModeView = View.Details
ObjExecQry.ViewData.NameFirstNode ="Servizi";
ObjExecQry.ViewData.set_FieldIndex(0, "Monitor");
//ObjExecQry.ViewData.set_FieldIndex(1, "Servizio");
ObjExecQry.ViewQuary();
ObjExecQry = null;
}
}
}
---------------------------------------- parte VB.net
' Private Delegate Sub ChgTreeView()
Private Sub objs_AnEvents(ByVal source As Object, ByVal Stato As Integer) Handles PCSObjS.Changed
Call pippo()
End Sub
Sub pippo()
']If Me.InvokeRequired() Then
'Me.Invoke(New ChgTreeView(AddressOf pippo))
'End If
Control.CheckForIllegalCrossThreadCalls = False
Dim tNode As TreeNode = New TreeNode()
Dim ObjExecQry As ExecuteQry.Application = New ExecuteQry.Application()
Me.trvService.BeginUpdate()
Me.trvService.ImageList = Me.ImageListS
Me.trvService.ImageIndex = 5
Me.trvService.SelectedImageIndex = 5
Me.trvService.Nodes.Add(New TreeNode("attvio"))
Control.CheckForIllegalCrossThreadCalls = True
End Sub
Ecco il questo è il codice sia di C# che di vb
chiaramente la parte vb è implemtata per fare una prova. ho provato anche con il delegate
ti ringrazio
freeteo
Profilo
| Guru
6.542
messaggi | Data Invio:
dom 8 giu 2008 - 19:02
il codice mi sembra corretto, se debugghi, ti passa per l'evento "objs_AnEvents" e ti va in errore?
Potrebbe essere un problema che si scatenano tanti eventi in rapida successione? In questo caso devi lavorare con il "lock" oppure dando al metodo che chiami l'attributo " [MethodImpl(MethodImplOptions.Synchronized)] " in modo che sia eseguito atomicamente...
Eventualmente puoi provare con "SuspendLayout() e ResumeLayout()" prima di aggiungere i nodi alla treeview per evitare l'appesantimento della parte grafica del controllo...
ciao.
Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo
maxmax03
Profilo
| Newbie
25
messaggi | Data Invio:
lun 9 giu 2008 - 13:15
ho provato anche con il nuovo controllo BackgroundWorker ma ottengo sempre lo stesso risultato. Non capisco per quale motivo non si riescono ad aggiornare i controllo su un thread separato dal principale. Sto verificando ancora su internet se ci fosse qualcuno che ha avtuo lo stesso problema
Se ti venisse in mente qualche altra soluzione suggeriscimela
grazie comunque
maxmax03
Profilo
| Newbie
25
messaggi | Data Invio:
lun 9 giu 2008 - 13:17
Mi sono dimenticato di dirti che l'evento funziona correttamente e che dal in cui creco di impostare il treeview va in errore
freeteo
Profilo
| Guru
6.542
messaggi | Data Invio:
lun 9 giu 2008 - 14:13
ciao,
guarda come procedimento deve funzionare,l'ho usato decine di volte, e lo stesso vale per il backgrroundWorker.
Ma qual'è l'errore dettagliato? è di cross-thread?
ciao.
Matteo Raumer
[MCAD .net]
http://blogs.dotnethell.it/freeteo
maxmax03
Profilo
| Newbie
25
messaggi | Data Invio:
lun 9 giu 2008 - 14:55
Si esatto Operazione cross-thread non valida
HO RISOLTO GRAZIE PER L'AIUTO
Torna su
Stanze Forum
Elenco Threads
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?
Dopo esserti registrato potrai chiedere
aiuto sul nostro
Forum
oppure aiutare gli altri
Consulta le
Stanze
disponibili.
Registrati ora !