[C#] Serialport deadlock in MS code

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
Ik heb een applicatie geschreven die communiceert met electrische verschroefmachines via ethernet.
De applicatie leest een barcode in met een scanner, die op een seriele poort zit en stuurt wat gegevens naar de verschroefmachine.

Ik krijg zo nu een dan een deadlock (geen cpu gebruik, UI werkt niet meer) en ctrl+alt+del is de enige oplossing. Ik gebruik 1 lock statement. Dit is als de port data stuurt om deze te verwerken. Alleen de poort zelf kan hierop moeten wachten (stel je zo 2x te snel scanneer en de vorige data is nog niet verwerkt)

Ik heb met DebugDiag een dump gemaakt de stack van de hoofdthread zit er zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
OS Thread Id: 0xba0 (0)
ESP       EIP     
0012eee8 7c90e514 [HelperMethodFrame_1OBJ: 0012eee8] System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean)
0012ef94 792b68af System.Threading.WaitHandle.WaitOne(Int64, Boolean)
0012efb0 792b6865 System.Threading.WaitHandle.WaitOne(Int32, Boolean)
0012efc4 7b6f1a4f System.Windows.Forms.Control.WaitForWaitHandle(System.Threading.WaitHandle)
0012efd8 7ba2d68b System.Windows.Forms.Control.MarshaledInvoke(System.Windows.Forms.Control, System.Delegate, System.Object[], Boolean)
0012f078 7b6f33ac System.Windows.Forms.Control.Invoke(System.Delegate, System.Object[])
0012f0ac 7b920bd7 System.Windows.Forms.WindowsFormsSynchronizationContext.Send(System.Threading.SendOrPostCallback, System.Object)
0012f0c4 7a924362 Microsoft.Win32.SystemEvents+SystemEventInvokeInfo.Invoke(Boolean, System.Object[])
0012f0f8 7a922a93 Microsoft.Win32.SystemEvents.RaiseEvent(Boolean, System.Object, System.Object[])
0012f144 7a923f8f Microsoft.Win32.SystemEvents.OnUserPreferenceChanged(Int32, IntPtr, IntPtr)
0012f164 7aa8f594 Microsoft.Win32.SystemEvents.WindowProc(IntPtr, Int32, IntPtr, IntPtr)
0012f168 003520a4 [InlinedCallFrame: 0012f168] 
0012f32c 7b1d8d2e System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)
0012f3c8 7b1d8997 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
0012f41c 7b1d87e1 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
0012f44c 7b195931 System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
0012f460 00d0021f DcTools.Main.Program.Main()
0012f69c 79e71b4c [GCFrame: 0012f69c]

en van de andere thread met een stack (de rest heeft geen stack en doet dus niets)
ziet er zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
OS Thread Id: 0xe34 (13)
ESP       EIP     
04a5f51c 7c90e514 [HelperMethodFrame_1OBJ: 04a5f51c] System.Threading.WaitHandle.WaitOneNative(Microsoft.Win32.SafeHandles.SafeWaitHandle, UInt32, Boolean, Boolean)
04a5f5c8 792b68af System.Threading.WaitHandle.WaitOne(Int64, Boolean)
04a5f5e4 792b6865 System.Threading.WaitHandle.WaitOne(Int32, Boolean)
04a5f5f8 792b682d System.Threading.WaitHandle.WaitOne()
04a5f600 7a9f5ddd System.IO.Ports.SerialStream+EventLoopRunner.WaitForCommEvent()
04a5f640 792d6d66 System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
04a5f64c 792e01ef System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
04a5f664 792d6ce4 System.Threading.ThreadHelper.ThreadStart()
04a5f88c 79e71b4c [GCFrame: 04a5f88c]



Dit zijn alle functie die niet door mij zijn gemaakt. Ik wil eigenlijk wel weten waarom de UI thread hierop wacht, ik dacht dat de seriele poort alles async deed, wat de oorzaak is en hoe ik dit op kan lossen.

Er zijn thoerieen die melden dat het apparaat van de poort halen die probleem kan veroorzaken, maar ik kan dit niet herproduceren.

ik heb hier wel wat zitten lezen. Ik betwijfel ook of het de seriele poort is, maar niet iets anders.


Ik heb zonet nog een crash voor mijn kiezen gekregen en de stack zit er hetzelfde uit.
Wat doet de OnUserPreferenceChanged in SystemEvents?

Ggole doet wonderen : info

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • ThaStealth
  • Registratie: Oktober 2004
  • Laatst online: 11-09 10:19
Is een lock statement wel nodig?

De serialport genereerd een event wanneer deze data binnenkrijgt. Wanneer er 2x achter elkaar gescanned wordt, dan wordt het event 2x achter elkaar aangeroepen (het 1e event heeft tijd genoeg om zijn data te verwerken).

Mess with the best, die like the rest


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
ThaStealth schreef op dinsdag 08 december 2009 @ 14:18:
Is een lock statement wel nodig?

De serialport genereerd een event wanneer deze data binnenkrijgt. Wanneer er 2x achter elkaar gescanned wordt, dan wordt het event 2x achter elkaar aangeroepen (het 1e event heeft tijd genoeg om zijn data te verwerken).
Ja, maar deze lock is niet de oorzaak van de deadlock.... De lock is idd nodig als er veel gescant wordt en de scanner is buiten bereik. Als deze weer binnen bereik komt gaat hij alle data versturen. Dit kan oplopen toch megabytes. Als ik geen lock doe gaan het mis.

Overigens wacht de lock 500ms en daarna knalt ie eruit. De lock wordt alleen hier toegepast en hij knalt er niet uit, dus is dat de oorzaak niet.

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • Phyxion
  • Registratie: April 2004
  • Niet online

Phyxion

_/-\o_

elgringo schreef op dinsdag 08 december 2009 @ 14:34:
[...]


Ja, maar deze lock is niet de oorzaak van de deadlock.... De lock is idd nodig als er veel gescant wordt en de scanner is buiten bereik. Als deze weer binnen bereik komt gaat hij alle data versturen. Dit kan oplopen toch megabytes. Als ik geen lock doe gaan het mis.

Overigens wacht de lock 500ms en daarna knalt ie eruit. De lock wordt alleen hier toegepast en hij knalt er niet uit, dus is dat de oorzaak niet.
SerialPort is blocking dus er zou als het goed is helemaal geen locks nodig hoeven zijn.

'You like a gay cowboy and you look like a gay terrorist.' - James May


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
Phyxion schreef op dinsdag 08 december 2009 @ 15:43:
[...]

SerialPort is blocking dus er zou als het goed is helemaal geen locks nodig hoeven zijn.
bij een datareceived event? Ik meende van niet....

Hoe dan ook, deze lock is niet het probleem.

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
De vraag is sowieso waar je op lockt?

Verder zou het wel fijn zijn als je een voorbeeldje geeft over hoe je de poort aanspreekt, en wanneer je een dead-lock krijgt.

Want op deze manier geef je ieder geval te weinig informatie.

[ Voor 16% gewijzigd door Woy op 08-12-2009 16:10 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
Als ik die link ( http://www.ikriv.com/en/prog/info/dotnet/MysteriousHang.html ) doorlees wordt de oorzaak en de oplossing gegeven. Kom je hiermee niet verder?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
Woy schreef op dinsdag 08 december 2009 @ 16:09:
De vraag is sowieso waar je op lockt?

Verder zou het wel fijn zijn als je een voorbeeldje geeft over hoe je de poort aanspreekt, en wanneer je een dead-lock krijgt.

Want op deze manier geef je ieder geval te weinig informatie.
Seriele poort geeft een datareceived event als ie wat data krijgt.
In deze event handler zit een lock op een lokaal object. Dit object hoort bij het object wat de poort gebruikt en wordt alleen hier gelockt.

In de lock zit data verificate (of de barcode goed is, of deze bestaat, etc.) Zodra dit gevalideert is komt hij uit de lock en stuurt asynchroon een event door (met meer info) naar de rest van de applicatie. Als de lock niet binnen 1 sec verkregen kan worden wordt er een log gegeneerd wordt de huidige data niet verwerkt. Dit laatste is niet voorgekomen.

De dead-lock krijg ik niet specifiek op een bepaald moment, soms is het tijdens productie, soms ook in de pauze als de applicatie niets doet.

Zoals ik al eerder aangaf. De door mij gemaakte lock is niet het probleem. En is een andere lock. De orozaak is een SystemEvent, UserPreferenceChanged. Die door OnUserPreferenceChanged aangeroepen wordt.

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
farlane schreef op dinsdag 08 december 2009 @ 18:27:
Als ik die link ( http://www.ikriv.com/en/prog/info/dotnet/MysteriousHang.html ) doorlees wordt de oorzaak en de oplossing gegeven. Kom je hiermee niet verder?
Ziet er wel aannemlijk uit, ik ga dit eens erin bouwen

Ik heb de freeze code van die site gedownload. Maar ik krijg hem niet 'gefreezed' om het zo maar te zeggen. Hij doet het dus niet. Heel apart.

Nog even iets:
In de situatie dat iets mis ging met de communcatie tussen verschroef machine en applicatie werd er wel een een form getoond met wat info. Deze werd op een andere thread dan het hoofdform aangeroepen. Volgens mij moet dit ook tot die problemen kunnen leiden.
Ik heb dit aangepast dat deze altijd op dezelfde thread als de hoofdthread wordt aangeroepen. In de loop van de dag zal ik wel wat feedback geven of dit werkte

[ Voor 49% gewijzigd door elgringo op 09-12-2009 07:54 ]

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • Phyxion
  • Registratie: April 2004
  • Niet online

Phyxion

_/-\o_

elgringo schreef op dinsdag 08 december 2009 @ 15:54:
[...]


bij een datareceived event? Ik meende van niet....

Hoe dan ook, deze lock is niet het probleem.
Je kan ook zelf gaan readen ;)

'You like a gay cowboy and you look like a gay terrorist.' - James May


Acties:
  • 0 Henk 'm!

  • elgringo
  • Registratie: Januari 2001
  • Laatst online: 16-09 20:30
Phyxion schreef op woensdag 09 december 2009 @ 08:33:
[...]

Je kan ook zelf gaan readen ;)
ik heb net zelf 'geread'. Datareceived event kan maar 1x actief zijn.

Pinchanged en error idem, maar van de rest ben ik nog niet overtuigd.

[ Voor 19% gewijzigd door elgringo op 09-12-2009 10:53 ]

if broken it is, fix it you should


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Dit lijkt me geen deadlock. Ten eerste heb je voor een deadlock twee locks (of andere geserialiseerde resources) nodig, ten tweede moeten die dan in twee threads gebruikt worden, en ten derde moet de ene thread de ene resource geclaimd hebben en de andere thread de andere.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • ThaStealth
  • Registratie: Oktober 2004
  • Laatst online: 11-09 10:19
MSalters schreef op woensdag 09 december 2009 @ 14:21:
Dit lijkt me geen deadlock. Ten eerste heb je voor een deadlock twee locks (of andere geserialiseerde resources) nodig, ten tweede moeten die dan in twee threads gebruikt worden, en ten derde moet de ene thread de ene resource geclaimd hebben en de andere thread de andere.
Het is een deadlock in Microsoft code, dus denk niet dat TS de (opzettelijke) veroorzaker is van de deadlock.

Mess with the best, die like the rest


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
De serialport code gebruikt achter de schermen een thread om een WaitCommEvent te doen, die dan vervolgens weer een threadpool thread gebruikt om een event naar user-code te krijgen.

Een en ander wordt hier ook uitgelegd: http://www.innovatic.dk/knowledg/SerialCOM/SerialCOM.htm

Conclusie: Seriele poorten zijn nog altijd fucked up in .Net

Hier ook een informatieve thread, met posts van een van de MS developers lijkt het: http://social.msdn.micros...08-42b3-86b7-adff82b19e5e

[ Voor 21% gewijzigd door farlane op 09-12-2009 16:47 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
farlane schreef op woensdag 09 december 2009 @ 16:33:
Conclusie: Seriele poorten is nog altijd fucked up in .Net
Ik gebruik altijd gewoon de BaseStream van de SerialPort, en dan heb je dat verhaal met threading niet zo. Dat werkt IMHO het makkelijkst. Al doe ik dat eigenlijk vooral omdat ik het makkelijker vind werken met een stream, dan met een SerialPort class. Op die manier kun je het later ook makkelijker door een andere stream vervangen.

[ Voor 23% gewijzigd door Woy op 09-12-2009 16:45 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
Woy schreef op woensdag 09 december 2009 @ 16:38:
Ik gebruik altijd gewoon de BaseStream van de SerialPort, en dan heb je dat verhaal met threading niet zo. Dat werkt IMHO het makkelijkst. Al doe ik dat eigenlijk vooral omdat ik het makkelijker vind werken met een stream, dan met een SerialPort class. Op die manier kun je het later ook makkelijker door een andere stream vervangen.
Ik moet zeggen dat ik seriele poorten waar het kan weg probeer te engineeren als ik aan .NET vast zit, heb nu al te veel van dit soort klote problemen gehad. Bugs die al versies lang in het framework zitten en maar niet worden gefixed etc.

Het geheel klinkt ook een beetje erm, overgeengineered als je die links doorleest.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
ThaStealth schreef op woensdag 09 december 2009 @ 16:16:
[...]

Het is een deadlock in Microsoft code, dus denk niet dat TS de (opzettelijke) veroorzaker is van de deadlock.
Ik leg net uit dat je voor een deadlock twee threads en twee locks nodig hebt. De vraag was niet wie er schuldig is, maar wat er daadwerkelijk gebeurt.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

Verwijderd

Heb zelf wel eens spontane deadlocks gehad bij de serial poort op het moment de ik de compoort sluit.
terwijl ik nergens locks gebruikte. het reseltaat was het zelfde als wat jij had de de UI hing. Later heb ik de compoort laten sluiten via een thread en deadlock was weg, was wel bij het compact framework maar dat maakt qua idee niet uit
Pagina: 1