PDA

View Full Version : سوال: فراخوانی مکرر یک پراپرتی از محلی ناشناس؟!!!



رافعی مهدی
جمعه 04 فروردین 1391, 00:29 صبح
با سلام
فرا رسیدن سال نو را خدمت همه دوستان تبریک عرض میکنم.

در یک پروژه نسبتاً بزرگ با مشکلی بسیار عجیب مواجه شدم. یکی از پراپرتیهای static که در کلاسی static قرار دارد، به طور مرموزی مدام فراخوانی میشود و نه با گذاشتن breakpoint و نه استفاده از متد System.Diagnostics.Debugger.Break، دیباگر روند اجرا را متوقف نمیکند تا Call Stack در get اکسسور این پراپرتی قابل بررسی باشد. از طرفی با دنبال کردن استک به طور دستی هیچ اطلاعات خاصی بدست نمی آید. کد مورد استفاده برای این کار به صورت زیر است:


public static MyType MyProp
{
get
{
Debugger.Break();

Debug.WriteLine("» get accessor of the 'MyProp'.");
Debug.Indent();
Debug.WriteLine("Current Thread : MTID = '" + Thread.CurrentThread.ManagedThreadId + "', Name = '" + Thread.CurrentThread.Name + "'");

StackTrace st = new StackTrace();
Debug.WriteLine("Frame Count : " + st.FrameCount);

for (int frameIndex = 0; frameIndex < st.FrameCount; frameIndex++)
{
StackFrame frame = st.GetFrame(frameIndex);
string methodName = frame.GetMethod().Name;

Debug.WriteLine(string.Format("Frame [{0}]: Method = '{1}'", frameIndex + 1, methodName));
}
Debug.Unindent();

// Rest of code...
}
}


با اجرای این برنامه و اطلاعات بدست آمده از کد فوق در پنجره Output، متوجه شدم که thread فراخوانی کننده این پراپرتی همان ریسمان اصلی برنامه است. اولین سوال این است که چرا روند اجرای برنامه در این scope توسط دستور Debugger.Break متوقف نمیشود؟

مسئله عجیب اینکه، تنها با یک بار فشردن دکمه F11 و درست پس از بارگزاری dllهای سیستمی و فقط چند dll (از میان بیش از 100 dll ایجاد شده در پروژه های متعدد در این Solution)، یعنی حتی قبل از اجرای یک خط از تابع Main، این پراپرتی فراخوانی میشود.


Output Window:


» get accessor of the 'MyProp'.
Current Thread : MTID = '10', Name = ''
Frame Count : 8
Frame [1]: Method = 'get_MyProp'
Frame [2]: Method = 'Main'
Frame [3]: Method = '_nExecuteAssembly'
Frame [4]: Method = 'ExecuteAssembly'
Frame [5]: Method = 'RunUsersAssembly'
Frame [6]: Method = 'ThreadStart_Context'
Frame [7]: Method = 'Run'
Frame [8]: Method = 'ThreadStart'



تمامی ارجاعات این پراپرتی با یافتن سیمبل آن (فشردن دکمه های Shift+Alt+F12 یا Shift+F12) بررسی شده و در همه آنها با استفاده از متد Debug.WriteLine نشانه ای برای پنجره Output در نظر گرفته شده، همچنین این پراپرتی در هیچ Constructor ای فراخوانی نشده است. اما همانطور که در بالا هم میبینیم، اثری از هیچ ارجاع دیگری بین فریم 1 و 2 نیست!!! این مسئله هنگامی غامض تر به نظر میرسد که با فشرده شدن دکمه F10 یا F11، در برخی موارد دوباره log فوق ظاهر میشود، به گونه‏ ای که Call Stack به کلی پاک شده و ارزیابی خطوط برنامه توسط دیباگر با خطای time out مواجه میشود.

از هر نکته مفیدی که ارسال شود، ممنون خواهم بود.

رافعی مهدی
جمعه 04 فروردین 1391, 22:49 عصر
امروز به طور اتفاقی نام پراپرتی مزبور رو تغییر دادم و این اشکال برطرف شد، ولی هرچی فکر میکنم چه conflict ای ممکنه بین نام پراپرتی من با چیزی که بخواهد اون رو مدام call کنه پیدا نکردم. اسم این پراپرتی BindingProjectList بود و در ورژن های قبلی پروژه بدون هیچ مشکلی کار میکرد. کسی در این مورد حدسی میزنه یا تجربه ای داره؟