25. november 2008 - 13:49Der er
20 kommentarer og 1 løsning
Summary "hint" i ClassLibrary - virker ikke!
Hvis man benytter nedenstående metode vil der fremkomme hints med den beskrivelse der er i summary for hver variabel, når man holder musen over en af variablerne... og det er jo ret genialt
Det virker bare ikke når jeg skal bruge metoden i ClassLibrary'et... inden for selve ClassLibraryet fremkommer de små hints!
Altså holder man musen over variablen "hoejde" fremkommer hint'et: "Højden af kassen i cm"
Er det bare sådan eller er det muligt at se disse hints/descriptions når man benytter sine DLL'er
Jeg håber der er nogel der forstår hvad jeg mener :-)
#region Manager Constructors /// <summary> /// Beregner rumfanget af en kasse /// </summary> /// <param name="hoejde">Højden af kassen i cm</param> /// <param name="laengde">Længden af kassen i cm</param> /// <param name="bredde">Bredden af kassen i cm</param> public Rumfang(Int hoejde, int laengde, int bredde) {
Først skal du gå ind på det projekt som du har lavet kommentarer til. Højreklik på projektet i Visual Studio, og tryk "Properties". Vælg "Build" tabben, og mærk af boksen "Xml documentation file". Næste gang du builder dit projekt, vil der blive genereret en XML fil som ligger ved siden af dll/exe filen. Når du kopiere dll/exe filen, så sørg for at kopiere denne xml fil med. Så længe XML filen ligger ved siden af dll/exe filen, vil du se kommentarene i Visual Studio.
Det virkede med det samme, så tak for det... du kan blot poste et svar!
Nu mens jeg har fat i dig,så kunne du måske hjælpe mig med et andet lille problem. Jeg har en datapakke hvor der er 4 returværdier. "ReturnValue1..4" string, int, float og bool samt en ennum "ReturnType" ( enum ReturnType{string=1,int, float, bool} )
Når pakken sendes afsted er ReturnType valgt...eks "int". så vil svaret blive konverteret til en int, men også til float og string, da det jo også er muligt.
Så når pakken kommer retur har man f.eks svaret både som int og string, men da man har valgt en returntype, skal det på en eller anden måde gøres enkelt at få det svar retur somman på forhånd har valgt at få, men man skal jo også kunne få fat i de andre typer.
Når der nu er 4 typer havde jeg tænkt noget lignende dette:
ReturnValue[ReturnType] ...altså lidt array of record agtigt, men ved ikke rigtig hvordan det skal laves i C#
Det er korrekt forstået, det er en datapakke der bliver sendt frem og tilbage mellem nogle dll'er via delegates. Det mest enkle er måske bare at resultatet returneres i den type man har valgt fra start... så må man selv konverterer til andre typer. Du kan herunder se den klasse som datapakken består af
Jeg har tænkt på at lave ReturnAnswer af typen object, men det har givet mig nogle nye problemer med invoke i applikatiionen. pt. virker det hvis ReturnAnswer er af typen string
public class HBDataPacket { //Interface selection public _Interface Interface = _Interface.None; //COMport settings public string COMStartStr; public string COMEndStr; public string COMTxStr; public string COMname; public int COMBaudrate; public bool COMIncludeStartStr; public bool COMIncludeEndStr; public int COMpacketsize; //CAN settings public string CANopen;
//Profi settings public string ProfiBus;
//MODbus settings public string Modbus; //Common settings public int PacketID; public int Max; public int Min; public string Unit;
public bool Read; public bool Write; public int ReTransmit; public int Timeout; public bool Error; public string ErrorMgs; public int TxTimeStamp; public int State;
public enum ReturnType {String=1, Integer, Floatingpoint, Boolean};
public string ReturnAnswer1; public int ReturnAnswer2; public float ReturnAnswer3; public bool ReturnAnswer4; }
Hmmm jeg tror faktisk jeg har fået det til at virke med ReturnAnswer som object.. jeg skal lige arbejde lidt mere med det før jeg er helt sikker på at det er den bedste løsning... så tusind tak!
Det der bare sker, er at abonnementet ligesom ikke bliver afsluttet før formen bliver lukket ned hvilket giver en exception. Hvis der konstant kommer data fra comporten ind i min applikation, opstår fejlen, for så bliver der jo konstant udvekslet data mellem mine delegates.
Hvordan kan man sikre sig at disse delegate er færdigafviklet inden formen lukker?
Hvis jeg stopper abonnementet selv inden jeg luker formen ned virker det perfekt!
Her er fejlbeskrivelsen:
System.ObjectDisposedException was unhandled Message="Der er ikke adgang til et fjernet objekt.\r\nObjektnavn: 'Form1'." Source="System.Windows.Forms" ObjectName="Form1" StackTrace: ved System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous) ved System.Windows.Forms.Control.Invoke(Delegate method, Object[] args) ved WindowsFormsApplication1.Form1.test(HBDataPacket datapacket) i C:\C#\DelegateTest\Application\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:linje 86 ved DeviceClassLibrary.HBDevice.OnDeviceData(HBDataPacket datapacket) i C:\C#\DelegateTest\DeviceClassLibrary\DeviceClassLibrary\DeviceClass.cs:linje 153 ved DeviceClassLibrary.HBDevice.DeviceDataRecieved(HBDataPacket datapacket) i C:\C#\DelegateTest\DeviceClassLibrary\DeviceClassLibrary\DeviceClass.cs:linje 160 ved MultiplexClassLibrary.HBMultiplex.OnMultiplexData(HBDataPacket datapacket) i C:\C#\DelegateTest\MultiplaxClassLibrary\MultiplexClassLibrary\MultiplexClass.cs:linje 21 ved MultiplexClassLibrary.HBMultiplex.MultiplexDataRecieved(HBDataPacket datapacket) i C:\C#\DelegateTest\MultiplaxClassLibrary\MultiplexClassLibrary\MultiplexClass.cs:linje 27 ved ComPortClassLibrary.HBComPort.OnComportData(HBDataPacket datapacket) i C:\C#\DelegateTest\ComPortClassLibrary\ComPortClassLibrary\ComportClass.cs:linje 341 ved ComPortClassLibrary.HBComPort.ComportDataRecieved(Object sender, SerialDataReceivedEventArgs e) i C:\C#\DelegateTest\ComPortClassLibrary\ComPortClassLibrary\ComportClass.cs:linje 326 ved System.IO.Ports.SerialPort.CatchReceivedEvents(Object src, SerialDataReceivedEventArgs e) ved System.IO.Ports.SerialStream.EventLoopRunner.CallReceiveEvents(Object state) ved System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state) ved System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) ved System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack) ved System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state) InnerException:
Jeg tænkte at dette måske kunne have en betydning Jeg er ikke helt med påhvordan dette her "invoke" fungerer, men jeg har denne fungerende stump kode, som jeg tænkte på måske kunen være årsagen!
if (this.richTextBox1.InvokeRequired) { testdelegate d = new testdelegate(test); this.Invoke(d, new object[] { datapacket }); }
Jeg tror det er din invoke som er problemet. Jeg går ud fra at du har noget kørende i en anden tråd, siden du bruger invoke?
I stedet for at bruge Thread eller ThreadPool, bør du bruge en BackgroundWorker for at starte en ny tråd. BackgroundWorker er beregnet til at skulle bruges sammen med en form. Da undgår du at skulle bruge invoke, og du undgår at der kommer en Exception når du lukker formen. Grunden til at du får denne Exception er, at selvom din form lukkes, køre tråden videre. På et eller andet tidspunkt prøver tråden at køre Invoke på formen, men formen er Disposed, og du får altså en Exception.
Jeg bruger kun delegates, men det er vel også en slags thread's. Hvis jeg manuelt aftryder tråden/abonnementet ved at eksekvere:
Device1.NewDeviceData -= new HBDevice.DeviceDataDelegate(DataRecieved);
inden jeg lukker formen får jeg ingen excption, men gør jeg det OnFormClosing, kommer den
Koden med invoke burde slet ikke kunne eksekveres da abonnementet jo er afsluttet. Jeg tror måske der sker det at jeg stopper abonnementet mens der stadig eksekveres kode i den metode som der blev sendt data til via delegates.
Når jeg så lukker formen er metoden stadig aktiv og kan så ikke få adgang til formen
Delegates køre i samme tråd som de bliver eksekveret fra. Hvis din Device klasse opretter en ny tråd og eksekverer delegatene derfra, har du flere tråde, ellers ikke.
Ifølge den stacktrace du har copy-pasted ind, ser det ud som om at fejlen sker i en metode som hedder test(HBDataPacket datapacket) på linje 86. Kan jeg se lidt mere af din kode?
Det er korekt, men hvis nu metoden test er blevet kaldet via en delegate og denne tråd afbrydes mens metoden test stadig eksekverer kode, så er det klart at metoden test ikke kan få fat i form1 som jo er ved at lukke ned, så hvordan sikre man sig at alle tråde er færdig afviklet inden formen afsluttes
Abonnement på delegate i DLL: Device1.NewDeviceData += new HBDevice.DeviceDataDelegate(DataRecieved);
Sådan starter og stopper jeg abonnement: NewData += new testdelegate(DataRecieved); NewData -= new testdelegate(DataRecieved);
Kode:
public delegate void testdelegate(HBDataPacket datapacket); public event testdelegate NewData;
public void DataRecieved(HBDataPacket datapacket) { OnData(datapacket); }
Det kan godt være det er en keglet måde at gøre det på, men deter deneneste måde jeg har fået det til at virke tilfredsstillende på, men i applikationen gør det ingen forskel om jeg har en event på delegate eller ej. Jeg havde først lavet det helt uden event... altså:
Device1.NewDeviceData += new HBDevice.DeviceDataDelegate(test);
Men det giver samme fejl
Kan det have noget med EndInvoke at gøre, for det her jeg ingen steder i min kode?
EndInvoke skal kun bruges sammen med BeginInvoke, som er en asynkron invoke. Det er ikke det der er problemet. Det ser ud til at HBDevice klassen køre i en anden tråd. Hvis alt kørte i din hovedtråd, ville dette problem ikke opstå.
Prøv:
public delegate void testdelegate(HBDataPacket datapacket); public event testdelegate NewData;
private bool isReceivingPackage = false;
public void DataRecieved(HBDataPacket datapacket) { OnData(datapacket); }
public void test(HBDataPacket datapacket) { this.isReceivingData = true; if (this.richTextBox1.InvokeRequired) { testdelegate d = new testdelegate(test); this.Invoke(d, new object[] { datapacket }); }
else { this.label6.Text = datapacket.GetReturnAnswerAsString(); //udskriver resultat til label this.richTextBox1.AppendText(datapacket.GetReturnAnswerAsStrin()); //udskriver resultat til richtextbox } this.isReceivingData = false; }
Fejlen opstår så snart Form1 er lukket ned, så brokker den sig over at der ikke mere er forbindelse til objektet "Form1". Så man skal på en eller anden måde ha fjernet tilhørsforholdet inden man lukker formen ned.
Jeg har testet med breakpoints at det ikke er er en ny pakke der kommer
this.isReceivingData = true; if (this.richTextBox1.InvokeRequired) { testdelegate d = new testdelegate(test); fejler her--> this.Invoke(d, new object[] { datapacket }); }
:-), jaja, virker det så virker det. Jeg tror næsten jeg ville blive nød til at sidde og rode lidt med det, hvis jeg skulle finde en mere elegant løsning. Men, din løsning virker, det er det vigtigste. :-)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.