i've experienced odd behavior in wpf application, when using double-checked locking create thread-safe singleton. code represents usual implementation of technique:
private _graphics contracts.interfaces.components.igraphics readonly property graphics contracts.interfaces.components.igraphics if _graphics nothing synclock lock if (_graphics nothing) _graphics = new gfx.application() end if end synclock end if return _graphics end end property when running program, got exception, because application-object constructed twice. couldn't believe eyes, since understanding of how locks work, tells me should thread-safe.
my presumption was, code running twice on same thread (asynchronously), ended modifying code analyse problem. adding list in order put thread-object every time thread steps locking statement. next, had compare contained thread-object current thread:
readonly property graphics contracts.interfaces.components.igraphics if _graphics nothing synclock lock if (_graphics nothing) if (threadlist.any() andalso (threadlist.first() isnot threading.thread.currentthread)) stop ' program stopping here. end if threadlist.add(threading.thread.currentthread) _graphics = new gfx.application() ' object construction takes around 70 ms. end if end synclock end if return _graphics end end property as might guess, program stopped, because multiple threads ran same locking statement. how can true? have absolutely no explanation behavior, let me know if have idea. thanks.
update: want add more details. initialization routine causes 2 anonymous methods run asynchronously. each of them accesses readonly property of singleton holder.
task.factory.startnew(sub() graphics.init(...) task.factory.startnew(sub() graphics.run(...) and here related disassembly instructions. perhaps give indication. here able follow these instructions:
if _graphics nothing 002d91ed cmp dword ptr ds:[38e3430h],0 002d91f4 sete al 002d91f7 movzx eax,al 002d91fa mov dword ptr [ebp-48h],eax 002d91fd cmp dword ptr [ebp-48h],0 002d9201 je 002d9297 synclock lock 002d9207 nop 002d9208 mov eax,dword ptr ds:[038e3438h] 002d920d mov dword ptr [ebp-40h],eax 002d9210 mov ecx,dword ptr [ebp-40h] 002d9213 call 518dce8c 002d9218 nop 002d9219 xor edx,edx 002d921b mov dword ptr [ebp-44h],edx 002d921e nop 002d921f lea edx,[ebp-44h] 002d9222 mov ecx,dword ptr [ebp-40h] 002d9225 call 7301a2b0 002d922a nop if _graphics nothing 002d922b cmp dword ptr ds:[38e3430h],0 002d9232 sete al 002d9235 movzx eax,al 002d9238 mov dword ptr [ebp-48h],eax 002d923b cmp dword ptr [ebp-48h],0 002d923f je 002d9264 _graphics = new gfx.application() 002d9241 mov ecx,47d664h 002d9246 call 73e601d2 002d924b mov dword ptr [ebp-4ch],eax 002d924e mov ecx,dword ptr [ebp-4ch] 002d9251 call 002d8c10 002d9256 mov eax,dword ptr [ebp-4ch] 002d9259 lea edx,ds:[38e3430h] 002d925f call 73e52360 end if 002d9264 nop end synclock
Comments
Post a Comment