PDA

View Full Version : پیغام خطا هنگام اجرای پردازش های سنگین



bita_naz
جمعه 09 تیر 1391, 11:12 صبح
سلام دوستان

هنگام اجرای یک پردازش سنگین که یا دیتابیس هم کار داره با پیغام زیر مواجه میشم

ContexSwitchDeadlock was detected
The CLR has been unable to transition from COM context 0x3d40b8 to COM context 0x3d4228 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.




لطفا راهنمایی بفرمایید
ممنون

ma.rad
جمعه 09 تیر 1391, 11:34 صبح
شما چند تا پردازش همزمان دارید؟از Thread استفاده کردید؟

Saeed_m_Farid
جمعه 09 تیر 1391, 14:06 عصر
سلام
اونطوری که خطا نشون میده، شما دارین از یک شیء COM در Tread اصلی (مثلاً فرم اصلی) استفاده می کنید (مثل اکتیوایکس، ابزارهای آفیس، ابزارهای سایر شرکتها مثل این (http://apihelp.httpwatch.com/#CSharp%20Overview.html) و ...) و در اینجور موارد هست که مفهوم Apartment threading مطرح میشه و COM ای که شما استفاده کردین STAThread (http://msdn.microsoft.com/en-us/library/system.stathreadattribute.aspx) (یا STA) هست (تفاوتش با MTA (http://stackoverflow.com/questions/127188/could-you-explain-sta-and-mta) و + (http://stackoverflow.com/questions/485086/single-threaded-apartments-vs-multi-threaded-apartments))، تو این مدل شما حق block کردن thread اصلی برنامه رو به مدت طولانی ندارین (اینجا 60 ثانیه) که در چنین حالتی برنامه به بن بست میخوره و همچین خطاهایی رخ میده؛ یعنی حق که دارین! ولی Application شما Not responding میشه و یا حافظه به فنا میره و ...
ما تو زبانهای native با CoInitialize این مشکل رو حل می کردیم، فکر کنم اینجا هم میشه؛ توضیح MSDN :



Objects created in a single-threaded apartment (STA) receive method calls only from their apartment's thread, so calls are serialized and arrive only at message-queue boundaries (when the Win32 function PeekMessage or SendMessage is called).x

Objects created on a COM thread in a multithread apartment (MTA) must be able to receive method calls from other threads at any time. You would typically implement some form of concurrency control in a multithreaded object's code using Win32 synchronization primitives such as critical sections, semaphores, or mutexes to help protect the object's data.x
When an object that is configured to run in the neutral threaded apartment (NTA) is called by a thread that is in either an STA or the MTA, that thread transfers to the NTA. If this thread subsequently calls CoInitializeEx, the call fails and returns RPC_E_CHANGED_MODE

ولی خوب راه های عاقلانه تری هم هست!!!
__________
بگذریم! برای چنین کارهایی بهتره BackgroundWorker استفاده کنید و کارهای سنگین تون (اون کامپوننت که کار سنگین انجام میده) رو بسپارید به اون و اجازه بدین فرمها و ... و کلاً Application شما روال عادی خودشون رو طی کنند. ضمناً اگه دقت کنید تو شرح خطا هم خودش گفته که می تونید از CoWaitForMultipleHandles استفاده کنید که خوب یه سطح پایین تر از BackgroundWorker یا Delegate/Invoke هست و بالطبع کمی مشکل تر و احتمال بروز خطا بیشتر میشه...

bita_naz
جمعه 09 تیر 1391, 14:57 عصر
شما چند تا پردازش همزمان دارید؟از Thread استفاده کردید؟

نه از Thread استفاده نکردم چون لازم نیست . این پردازش یک دستور for عادی هست که داده ها رو از یه فایل xml میخونه و بعد از convert توی دیتابیس Insert میکنه. وقتی فایل xml بزرگ میشه و به چند هزار رکورد میرسه این مشکل رو دارم و برای تعداد کم رکورد این خطا رخ نمیده .
البته همونطور که دوستمون Saeed_m_Farid (http://barnamenevis.org/member.php?41415-Saeed_m_Farid) بطور درست فرمودن من از کامپوننت های ThirdParty استفاده کردم در فرمم. از DotnetBar استفاده کردم. و یک ProgressBar که جزو اون کامپوننت هست رو دارم هنگام پر شدن دیتابیس نشون میدم و پر میکنم. ولی DotnetBar کامپوننت COM نیست . دات نت هست. واسه خودم هم عجیبه
دلیل عدم استفاده از BacgroundWorker یا MuliThreading هم اینه که برنامه طوری هست که حتما باید اون پردازش تموم شه تا بعد کاربر اجازه داشته باشه کاری کنه وگرنه برنامه بهم میریزه
البته این رو هم بگم همیشه این مشکل همیشه پیش نمیاد. پنچاه پنجاه هست . بعضی اوقات تا 10000 رکورد Insert میکنم که چند دقیقه طول میکشه و همه چیزم درسته و بدون خطا

لطفا راهنمایی بفرمایید

Saeed_m_Farid
شنبه 10 تیر 1391, 00:35 صبح
نه از Thread استفاده نکردم چون لازم نیست ...
دلیل عدم استفاده از BacgroundWorker یا MuliThreading هم اینه که برنامه طوری هست که حتما باید اون پردازش تموم شه تا بعد کاربر اجازه داشته باشه کاری کنه وگرنه برنامه بهم میریزه
فرقی نمی کنه، بازهم شما می تونید از BackgroundWorker (یا Thread جداگانه) استفاده کنید و تا وقتی کارتون تموم نشده، فرم رو قفل کنید یا دسترسی ها رو محدود کنید، کار که تموم شده یه سیگنال به فرم بفرستید و کار عادی برنامه رو ادامه بدین...
بهر صورت کامپوننت ThirdParty شما هرچی هم باشه داره از STAThread (http://msdn.microsoft.com/en-us/library/system.stathreadattribute.aspx) استفاده میکنه و بهتره در Thread جداگانه پردازش بشه...