PDA

نسخه کامل مشاهده نسخه کامل : سوال : targetInvocationException



without_all
10-02-2010, 17:02
سلام

ّبه این عکس یه نگاه بندازید ببینین این چه مشکلی داره

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

_H2_
17-02-2010, 00:00
سلام
احتمالاً خطایی در کدهای خود design فرم دارید که VS خط دقیق مربوطه را نشانم نمیدهد.
با توجه به اینکه (من وقت نداشتم) از تاپیکتان هم یک هفته ای گذشته، آیا همچنان مشکلتان وجود دارد یا حل شد؟
اگر وجود دارد، در همینجا اطلاع دهید تا مشکل را با هم پیگیری و انشاا... رفع کنیم.

موفق باشید.

without_all
17-02-2010, 13:42
سلام
احتمالاً خطایی در کدهای خود design فرم دارید که VS خط دقیق مربوطه را نشانم نمیدهد.
با توجه به اینکه (من وقت نداشتم) از تاپیکتان هم یک هفته ای گذشته، آیا همچنان مشکلتان وجود دارد یا حل شد؟
اگر وجود دارد، در همینجا اطلاع دهید تا مشکل را با هم پیگیری و انشاا... رفع کنیم.

موفق باشید.
سلام

آقا دمت گرم من هر روز سر میزدم تازه میخواستم پ.خ بهتون بدم:31:

این Exception کمر منو شکسته :19:

من هر موقع از کنترل BackgroundWorker استفاده میکنم ای خطا رخ میده برنامه من یک google,URL رو میگیره (یعنی اونURL یه Search,URL است ) و از داخل source اون لیست سایت های پیدا شده توسط گوگل رو در میاره بعدش برای تک تک اون سایت ها باز source اونارو میکیره و داخل Source g اونا دنبال یه عبارت خاص میگرده و فقط روی URL های خاصی این اتفاق رخ میده

برنامه تا آخر درست کار میکنه یعنی میدونم تا آخرین ساتو چک میکنه فقط برنامه وقتی میخواد خاتمه پیدا کنه Exception بر میگردونه
من از VS 2010 استفاده میکنم وگرنه براتون برنامه رو میفرستادم

without_all
17-02-2010, 14:01
سلام

همش Exception یک Exception دیگه :41:
شما میتونی برنامه های نوشته شده با VS 2010 رو اجرا کنی و کدشو ببینی اگه میتونی من برنامه رو برای شما پ.خ کنم دو تا URL هم بهتون بدم اجرا کنید Exception هاشو ببنید لطف کنید ببینید کجاش ........ و به من Noob یه توضیح بدید :20:
البته میدونم وقت ......
:20:

_H2_
17-02-2010, 23:24
سلام

من هر موقع از کنترل BackgroundWorker استفاده میکنم ای خطا رخ میده
خوب عزیز دل بابا! چرا خودتان و ملت را سر کار میگذارید :31: زودتر میگفتی! :31:
( آقا شوخی کردم ها بعداً نگید چه ادم خشنیه! :31: )

مسئله چند ریسمانی اگر درست انجام نشود میتواند منشاء خطاهای به ظاهر عجیب و بیموقع باشد.
انشاا... از کنترلر WebBrowse که استفاده نکردید؟ (چون نیازی نبوده)

احتمالاً در روال ریسمان جدیدتان به کنترلری روی فرم ارجاع داده اید؟ یعنی مثلاً Text یا BackColor کنترلری روی فرم را خوانده یا عوض کرده باشید؟


شما میتونی برنامه های نوشته شده با VS 2010 رو اجرا کنی و کدشو ببینی
گرچه مجدد در چند روز گذشته نسخه جدید از VS2010 به نام Visual Studio 2010 Ultimate RC عرضه شده معمولا تا نسخه Full چیزی نیاید، نصبش نمیکنم.

اما گمانم بتوانم پروزه را یکجوری باز کنم.
سعی کنید تا جایی که میتوانید پروزه کوچک و ساده تری باشد و اصل قسمت مشکل دار را بفرستید.

=====

بحرحال بدون شک ایراد از تابع Main شما نیست و با این سه خط کد نمیتوان ایراد واقعی را تشخیص داد.
کدهای ریسمان مجزا شما در BackgroundWorker حداقل باید باشد و چک شود.
موفق باشید.

without_all
18-02-2010, 01:14
انشاا... از کنترلر WebBrowse که استفاده نکردید؟ (چون نیازی نبوده)

خدا رو شکر که استفاده نکردم (چون یه فکرایی داشتم :31:)


مسئله چند ریسمانی اگر درست انجام نشود میتواند منشاء خطاهای به ظاهر عجیب و بیموقع باشد

با این حرفت روحم شاد شد:11:

برنامه رو پ.خ میکنم اونجا میگم چرا ولی شما لطف کن جوابو اینجا بزار تا یکی دیگه مثل من اینجوری نشه ( چشمام دیگه باز نمیشه از بس search کردم )

ممنون

_H2_
19-02-2010, 18:24
سلام
کدتان را دانلود کردم

همانطور که حدس زده بودم، شما استفاده صحیحی از مباحث چند ریسمانی ندارید...
من که کلاً گیج شدم که چرا به این شیوه عجیب کار کردید.

اصل ریسمان مجزا یک backgroundworker رویداد DoWork است که شما فقط بخش دانلود را در این رویداد انجام داده بودید و کل حلقه های پردازش شما در رویداد RunWorkerCompleted بود که همان ریسمان اصلی برنامه است و برای همین هم دوباره فرم هنگ میکرده و DoEvents استفاده کرده اید و باز ناچار و مجبور شده بودید backgroundworker دوم را اضافه کنید تا برنامه تان در RunWorkerCompleted هنگ نکند!!!!
بعد هم دوباره مجبور شدید برای سینک کارها آن حلقه عجیب و کمی شگفت انگیز (!:31:!) داخل متد bug_finder را قرار دهید و باز از DoEvents هم برای هنگ نکردن فرم استفاده کنید !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

آخه برادر! اینکه چند ریسمانی نمیشود که شما کد را با همان ریسمان اصلی در RunWorkerCompleted اجرا کنید و باز مثل برنامه های غیر چند ریسمانی برای هنگ نکردن فرم DoEvents اضافه کنید.
اصلاً برنامه چند ریسمانی تقریباً نیازی به DoEvents ندارد!

خوب چه کاریه؟!
کافی است همه کارهایتان تحت DoWork اولی انجام شود!

=====

از طرف دیگر متغیرهایی که خیلی راحت میتوانست آرگومان ورودی توابع باشد را در سطح کلاس ذخیره کرده اید؟؟؟!

=====

چند شرط هم اصلاً کلاً به نظرم زیادی هستند یا مشکل داشتند!
مثلاً

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
خوب یک رشته که با href شروع شود حتماً برابر "# نیست!!!
شرط دوم زائد است.

یا


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
خوب این شرط که همواره برقرار است!!!! :31:
یک مسئله ساده شی گرایی است!
شی objListView که تازه new شده (و بازتعریف اپراتور تساوی ندارد) چطور امکان دارد با اشایی که قبلاً new شده یک اشاره گر داشته باشد!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

اگر میخواستید چک کنید متن تکراری نباشد حداقل باید این کد را مینوشتید:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

=====

بحرحال کد شما را به روش منطقی و اصولی ویرایش کردم و محل قطعات کد شما را جابجا کرد تا اعمال در همان DoWork و با یک backgroundworker انجام شود.
بعد از این اصلاحات کوچک کد دیگر خطا نداد.
نمیدانم دقیقاً خطا مربوط به کدام یک از ابتکارات جالب شما در چند ریسمانی میشد! :31: ولی بحرحال با حذف ابتکارات شگفت انگیزتان مشکل رفع شد. :31:

=====

ضمناً روش خواندن HTML و یافتن HRef های شما هم کامل و خوب نیست.
HTML که در و پیکر و قانون ندارد!

خصیصه "href" میتواند چند فاصله تا "=" داشته باشد و خود "=" با رشته ...
میتوان اول و آخر مقدار تک کتیشن باشد یا جفت کتیشن باشد و یا حتی هیچ چیز نباشد!!!!

تازه معلوم نیست href که شما پیدا کرده اید برای یک تگ A باشد؟ شاید در متن معمولی فرد آن را نوشته!
و...

بعد هم متد Split شما برای اطلاعات حجیم خیلی سرعتتان را کاهش میدهد در نهایت هم به دلایل فوق کد مستحکم نخواهد بود و همیشه صحیح کار نمیکند.

من برای خواندن HTML و سایر فرمت های مشابه کلاسی درست کردم که میتوانید نمونه کدش را در پک زیر مشاهده کنید.
support.h02.ir/fwlink/?LinkId=1005415457

ضمن اینکه سیستم کار کلاس فوق و ONE SCAN و FAST FORWARD و READONLY است که این سه شرط باعث سرعت فوق العاده ان میشود و در واقع نوعی Html Parser پرسرعت را تشکیل میدهد که همه حالات HTML با خطاهای رایج HTML را میشناسد و میخواند ...

=====

راستی چرا فقط ورودی گوگل را میخوانید؟؟؟؟؟
نکند بخاطر لینک های نسبی باشد؟؟؟؟؟؟؟؟؟؟

و...
و...
و...

کدتان را یک بار دیگر چک میکنم و انشاا... به زودی آپلود میکنم و در پ.خ لینک میدهم.

=====

موفق باشید.

_H2_
19-02-2010, 18:35
سلام

این صرفاً یک پست اموزشی کوتاه برای دوستان در ارتباط با چند ریسمانی و استفاده از کامپونت backgroundworker است.

=====

اول برای درک بهتر مفهوم چند ریسمانی حتماً این تاپیک (مخصوصاً پست 7 و پست 9) را مطالعه کنید:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

پس از مطالعه دو پست فوق ...


در کد زیر جاهایی که با main thread مشخص شده را ریسمان اصلی برنامه اجرا میکند و new thread ها را ریسمان جدیدی که با backgroundworker.dowork آغاز شده.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

متد btnStart_Click را ریسمان اصلی فرم اجرا میکند و متد RunWorkerAsync ریسمان جدیدی را به خدمت میگرد که لحظاتی بعد ریسمان جدید با اجرای دستورات داخل متد backgroundWorker1_DoWork کارش را شروع میکند.
هر زمان دستورات داخل backgroundWorker1_DoWork تمام شود ریسمان جدید به کارش خاتمه میدهد و پیامی برای ریسمان اصلی برنامه جهت اجرای backgroundWorker1_RunWorkerCompleted میفرستد.

backgroundWorker1_RunWorkerCompleted توسط ریسمان اصلی خود برنامه اجرا میشود و نباید حاوی پردازش سنگین باشد ...
فقط نتایج کار را چاپ یا نمایش دهد و احیاناً کنترلی که غیر فعال شده بوده را مجدد فعال کند و...

در عوض تا وقتی پردازش داخل backgroundWorker1_DoWork و توابعی که در این متد صدا زده میشود باشد، ریسمان جدید آن را اجرا میکند و فرم هم قفل نمیکند چون ریسمان اصلی آزاد است و فرامین کاربر را روی فرم انجام میدهد.
در این متد هیچ DoEvents هم نیاز نخواهد بود.

=====

دات نت یک مکانیزم عدم تداخل+امنیتی دارد که اجازه دسترسی به کنترلرها فرم را از سایر ریسمان ها نمیدهد.
(((
میتوان این مکانیزم را خاموش کرد ولی پیشنهاد نمیکنم، ضمن اینکه در شرایط خاص باز میتواند مشکل ساز شود، از آن مشکلاتی که افراد غیر آشنا به مکانیزهای داخلی را گیج و دیوانه میکند! پس همینطوری روش باشد بهتر است! :31:
)))

ولی بحرحال ما در متد backgroundWorker1_DoWork یا ریسمان های دیگر گاهاً نیاز به دستکاری کنترلرها مثلاً در جهت نمایش میزان پیشرفت کار داریم.
برای اینکار میتوان از تلفیق خصیصه InvokeRequired و متد BeginInvoke استفاده کرد.

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
کد فوق اول با if ریسمانی که دستورات را اجرا میکند چک میکند.
اگر ریسمان اصلی نباشد شرط برقرار میشود و پیغامی برای ریسمان اصلی گذاشته میشود تا هر وقت فرصت داشت یکبار همین متد (TextReport) با پارامترهالیی که حالا دارد (text) اجرا کند!!! (چه با شخصیت! :31:)

این کار مثل ان میماند که در اداره ای، کاغذ و پرونده ای را برای پیگیری روی میز یک کارمند قرار دهید تا هر وقت کار نداشت و نوبت این پرونده رسید، این را هم بررسی کند و کارش را انجام دهد.
و خودتان بگذارید و بروید به کارتان برسید.

این کار در برنامه نویسی چندین مزیت دارد:
1- مشکل خطای تداخلی/امنیتی Cross (که قبلاً بیان شد) پیش نمی اید و ریسمان جدید مستقیماً چیزی روی فرم را تغییر نمیدهد.

2- اگر ریسمان جدید خودش بخواهد کنترلرهای روی فرم را تغییر و ترسیم کند، طبیعتاً بخشی از وقتش گرفته میشود و جمع زمان عملیاتش طولانی تر میشود.
مثل وقتی که خودتان بروید دنبال کار یک پرونده تا اینکه پرونده را روی میز کارمند مسئول بگذارید تا خودش ان را انجام دهد و شما بروید به ادامه کار خودتان برسید!!!

3- برخی از کنترلرهای خاص که در هسته سیستم عامل مدیریت میشوند اگر از ریسمانی که صف پیغامها را در دست ندارد تغییر رویش اعمال شود، تغییرات را سریع روی مانیتور نشان نمیدهد و عملاً کنترلر آپدیت نمیشود.
در حالیکه با دستور فوق به علت انکه ریسمان اصلی سرش خلوت است فوراً این کار را به بهترین و صحیح ترین نحوش انجام میدهد و ریسمان جدید هم که به ادامه کار پردازشی خودش میرسد.

نتیجتاً هر زمان در کدهایی که از ریسمان جدید اجرا میشود خواستید کنترلرهای روی فرم را تغییر دهد (متن و رنگ و...) با این مکانیزم تلفیقی InvokeRequired و BeginInvoke این کار را انجام دهید.

=====

ضمنا در همچین کدی استفاده از DoEvents جایگاهی ندارد!
هر جا DoEvents را به [B]قصد هنگ نکردن فرم[B] گذاشتید بدانید که دارید با ریسمان اصلی کاری را انجام میدهید نه ریسمان جدید و مجزا .

=====

البته به نظر شخصی من استفاده مستقیم از کلاس System.Threading.Thread ساده تر از System.ComponentModel.BackgroundWorker است.
مایکروسافت خواسته در System.ComponentModel.BackgroundWorker کار چند ریسمانی را برای عموم ساده تر کند ولی به نظر شخصی من چندان تفاوتی نکرده!
و نحوه استفاده خیلی شبیه هم و یکسان است.

=====

مطالب گفته شده عیناً برای VB.Net صادق است و زبان برنامه نویسی فرقی نمیکند.
جمیعاً موفق و شاد باشید.
:10:

without_all
19-02-2010, 20:17
آقا نمیدونم چطور تشکر کنم :11::11::11::11::11::11::11:

این گلا که فایده نداره نمیشه باهش تشکر کرد


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید:20:

بازم ممنون

without_all
19-02-2010, 20:38
جناب H2 پست شماره 7 رو که میخوندم ترکیدم
پس از بس گل کاشته بودم شده بود یه باغ زیبا :27: درسته من قبلا باغبون بودم :31:

این کلاسی که شما نوشتید که از کل برنامه من یه Kb 40 که بیشتره (شوخی)

شما Master هستی :46: من noob احتمالا مدت زیادی برنامه نویسید
من خودم شروع به یا گیری کردم نمخوام توجیه کنم ولی برام سخته یکم

در مورد سوالات :

چون داخل source سایت های وجود داشت که مال google بود ولی دلیل اصلیش این بود که گوگل تنها متور جستجویی که ( الیته شاید باشه و من نمی دونم ) که از داخل URL های سایتها چیز خاصی رو جستجو میکنه


خب کدی که آپلود کردیدو برسی کردم میدونم زمان پست منو خودتونو مقایسه کردی نو فهمیدین چه سریع :27:

چون کد برام سنگین بود و بعضی قسمت های کدو نفهمیدم و اگه اجازه بدید سوالای مبتدیانمو آغازکنم ( اگه اجازه دادید :31::20: فقط بگید تاپیک جدید بزنم تا جستجو برای بقیه آسون باشه یا همین جا بپرسم)من مسمم که #C رو یاد بگیرم

_H2_
20-02-2010, 00:26
سلام

من خودم شروع به یا گیری کردم
ما همه و همه روزه در حال یادگیری هستیم ...
نمیدانم تا کجا پیش رفته اید و تاکید میکنم حتماً همه کلمات کلیدی زبان کاری تان + مفاهیم و پیاده سازی شی گرایی و وراثت و پلی مورفیزم را یاد بگیرد.
بدون دانستن مطالب فوق الذکر دانش برنامه نویسی هر کسی خیلی ناقص خواهد بود.


کد برام سنگین بود و بعضی قسمت های کدو نفهمیدم
!!! من فقط کدهای خودتان را defragment کردم !!!
کمی جای قطعات کدهای خودتان را جابجا کردم، تقریباً کدی اضافه نکردم.
این برنامه من نیست، این برنامه خودتان است که defragment شده.


فقط بگید تاپیک جدید بزنم تا جستجو برای بقیه آسون باشه
نمیدانم!
اگر فکر میکنید سوالتان نسبت به تاپیک فعلی خیلی بی ربط است(!) در تاپیک مجزا مطرح کنید.
ولی اگر فکر میکنید سوالتان در راستای همین مباحث چندریسمانی است که در تاپیک صحبت شده، خوب همینجا مطرح کنید تا کنار هم باشند
!!!!!

=====

تلاشتان را بیشتر کنید، باید روی کدتان کار کنید، کارتان شروع شده، مطمئن باشید کدتان جای کار زیاد دارد و فقط مشکل چندریسمانی حل شده.
موفق باشید.
:10:

without_all
22-02-2010, 11:35
سلام



پلی مورفیزم را یاد بگیرد


- اینو نمیدونم چیه ؟ :20:


!!! من فقط کدهای خودتان را defragment کردم !!!

- حق با شما بود من تنبلی کرده بودم :43:


سوالاتم :

1- این کدو اگه میشه یه توضیح :


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

مخصوصا قسمت قرمز رنگ .

2- و این کد رو هم :


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

3- چرا در بیشتر جاها از This استفاده میکنید دلیل خاصی داره ؟

4- این دوتا چه کاربردی دارن :


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید



ممنون :15: ( زیاد خیلی زیاد )

با تشکر
Woeful

_H2_
22-02-2010, 19:01
سلام

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
Polymorphism یا همان چندریختگی اجازه میدهد کلاسهایی از شاخه های وراثتی مختلف الگو و پیاده سازی یکسانی را شامل شوند.
مثلاً
جانداران->حیوانات->خرگوش!
جانداران->گیاهان->گل لاله!
بی جان->ابزار (ساخته بشر)->وسایل نقلیه->خودرو->پیکان!

کلاس "پیکان" از یک شاخه وراثتی مختلف است و نمیتواند رابطه وراثتی مستقیمی با کلاس "خرگوش" و ربطی به هم ندارند.
از دو شاخه درخت متفاوت منشاء شده اند ولی با این وجود هر دو متد "حرکت" دارند!!!
اینجاست که وراثت اجازه پیاده سازی این امکانات مشابه از شاخه های وراثتی مختلف را نمیدهد. (مخصوصاً در دات نت که هر کلاس فقط و فقط میتواند و باید از یک کلاس وراثت بگیرد)

در اینجا پلیمورفیزم این شاخه های مختلف را به هم وصل میکند.
در دات نت با کلمه Interface میتوان یک رابط را تعریف کرد.
و در #C با علامت ":" و "," میتوان واسط در کلاس پیاده سازی کرد.
و در VB با کلمه Implements میتوان واسط را در کلاس پیاده سازی کرد.



1- این کدو اگه میشه یه توضیح :
System.Collections.Generic.IList

IList واسط همگانی یک فهرست اشیا است. (همان Polymorphism !)
در متد دومتان به جای انکه یک List بگیریم یک IList گرفتیم! چرا؟
برای ایزوله تر شدن دو متد، به این معنی که اگر تابعی که این تابع را صدا میزد هر نوع لیستی درون خودش تعریف کرده باشد و یا بعداً نوع ان را تغییر دهد باز هم متد دوم میتواند صحیح کار کند و نیاز به تغییر ندارد.
متد دوم نیاز ندارد بداند که متد اول دقیقاً چه نوع فهرستی را در خودش new و پر کرده.

مثلاً کلاس System.Collections.Generic.List واسط IList را دارد!
کلاس System.Collections.ObjectModel.Collection هم واسط IList را دارد!
و همینطور کلاسهای System.Windows.FreezableCollection و System.Collections.ObjectModel.ReadOnlyCollection و System.Collections.Generic.SynchronizedReadOnlyCol lection و... واسط IList را دارند.

و متد دوم ما میتواند با هر یک از کلاسهای فوق صحیح کار کند!
یعنی اگر نوع کلاس در متد بالاسری تغییر کند تا زمانی که کلاس واسط مورد نیاز را داشته باشد متد دوم نیاز به تغییر ندارد و کد مستحکم تر میماند و با یک تغییر کوچک کمتر نیاز میشود جاهای دیگر هم تغییر کنند.

(((
گرچه در کد فوق واسط پایه ای تر System.Collections.Generic.ICollection و یا حتی واسط System.Collections.Generic.IEnumerable هم برای foreach کافی بود!
اگر خودم بودم احتمالاً با یک از این دو کد را مینوشتم!
)))

این از جمله همان کاربردها و مفاهیم چندریختگی یا پلیمورفیزم است که اشیای مختلف را در یک متغییر یکسان جای میدهد.



2- و این کد رو هم :
InvokeRequired, Invoke

اینها را که در پست 8 تاپیک خودتان توضیح دادم!!!
دقیقاً نصف پست 8 به توضیح این مطلب اختصاص یافته!
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]



3- چرا در بیشتر جاها از This استفاده میکنید دلیل خاصی داره ؟

کلمه this حاوی اشاره گر کلاس جاری است.
وقتی شما متغیر یا متدی یک نمونه کلاس را میخواهید فراخوانی کنید مینویسید classvariantname.Method
در یک یک کلاس بخواهید متغیر و متد و اعضای همان کلاس را فراخوانی کنید در واقع دارید اعضای this را فراخوانی میکنید.
البته نوشتن this اختیاری است چون در واقع پیش فرض است.

بحث طولانی میشود ...
نوشتن یا ننوشتن this اختیاری است ولی من با نوشتن this احساس وفاداری بیشتری به شی گرایی پیدا میکنم!



private delegate void AddListViewItemDelegate(string text, string description);
private delegate void OneTextDelegate(string value);

delegate ها میتوانند اشاره گر (چیزی شبیه Shortcut ویندوز!) یک تابع را در خود جای دهند.
در واقع ما اشاره گر متدی را که میخواهیم ریسمان اصلی (هر وقت داشت) اجرایش کند با delegate مناسب بسته بندی میکنیم و به صف کارهای ریسمان اصلی اضافه میکنیم.
بحرحال ریسمان باید بداند چه متدی (و با چه پارامترهایی) را ما میخواهیم اجرا کند؟؟!!
و این Shortcut همان متد است.

توضیح بیشتر و تاپیک مرتبط:
[ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ]

موفق باشید.

without_all
23-02-2010, 17:38
اینها را که در پست 8 تاپیک خودتان توضیح دادم!!!
دقیقاً نصف پست 8 به توضیح این مطلب اختصاص یافته!

درسته ولی من متوجه نشدم احتمالا به خاطر اینکه با delegate همراه شده
من در کتاب آموزش #C دنبال delegate گشتم و دیدم در عمق فصلهای شئ گرایی قرار داره ( همون فصلهایی که همیشه ازشون فرار میکردم ) فک میکنم دیگه باید باهاشون روبه روشم شما ببینید این چیزی که من فهمیدم درستته یا اشتباه ؟

در توضیح این کد :

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

if چک میکنه اگه ریسمان اصلی ما فعلا کار داره یه درخواست(required) برای مراجعه به این قسمت در لیست کارهایی که ریسمان اصلی در موقع بی کاری قراره انجام بده قرار میده

همین جا یه سوال :

آیا اینجا یعنی ریسمان جدید متوقف میشه تا ریسمان اصلی به اینجا مراجعه کنه و بعد از انجام کار ریسمان اصلی ، دوباره ریسمان جدید کارش رو شروع میکنه ؟

ادامه :
خب فرض میکنیم ریسمان اصلی ما الان بیکار شده و اومده invoke چیکار میکنه؟ ( مخصوصا پارامتر هاشو من درک نمیکنم) دوباره خود AddFoundSite رو احظار میکنه ؟ یعنی یه حلقه میشه ؟

یا اگه از یه جنبه دیگه بهش نگاه کنیم :

if چک میکنه اگه ریسمان اصلی ما فعلا کار داره یه درخواست(required) برای مراجعه به این قسمت در لیست کارهایی که ریسمان اصلی در موقع بی کاری قراره انجام بده قرار میده

خب ریسمان اصلی الان بی کار شده اومده به جایی که ما درخواست کرده بودیم
ریسمان اصلی دوباره تابع AddFoundSite احظار میکنه و چون سرش سلوغ نیست این کد رو اجرا میکنه :

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

و این نمیتونه مثل یه تابع بازگشتی باشه و نباید ما کد رو به این صورت اصلاح کنیم :

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

من کد شما رو اجرا کردم میدونم درست کار میکنه ولی این سولا برای من پیش اومده و کاملا کیچ شدم


در ضمن اگه این سولایی که من کردم به شئ گرایی ربطی داره جواب ندید من میرم فصلای شئ گرایی
رو از اول مخونم


میبخشید اگه من یه کم پا پیچ شدم


با تشکر
Woeful

_H2_
24-02-2010, 20:57
یلام


... چک میکنه اگه ریسمان اصلی ما فعلا کار داره ...

من همچین چیزی نگفتم!
یاداوری ...


کد فوق اول با if ریسمانی که دستورات را اجرا میکند چک میکند.
اگر ریسمان اصلی نباشد شرط برقرار میشود و پیغامی برای ریسمان اصلی گذاشته میشود تا هر وقت فرصت داشت یکبار همین متد (TextReport) با پارامترهالیی که حالا دارد (text) اجرا کند





آیا اینجا یعنی ریسمان جدید متوقف میشه تا ریسمان اصلی به اینجا مراجعه کنه و بعد از انجام کار ریسمان اصلی ، دوباره ریسمان جدید کارش رو شروع میکنه ؟

همانطور که اشاره ای کردم ...


این کار مثل ان میماند که در اداره ای، کاغذ و پرونده ای را برای پیگیری روی میز یک کارمند قرار دهید تا هر وقت کار نداشت و نوبت این پرونده رسید، این را هم بررسی کند و کارش را انجام دهد.
و خودتان بگذارید و بروید به کارتان برسید

برای سایر ریسمان ها if برقرار میشود و با ان متد خاص BeginInvoke فقط اجرای این تابع(AddFoundSite) به عنوان یک پیغام به صف کارهای ریسمان اصلی اضافه میشود.
سپس ریسمان فعلی یا همان جدید این پیغام را POST میکند و میرود خط بعد را که return است اجرا میکند و بعد هم سایر دستوراتی که در روال بالاسری باید اجرا میشدند.

مثل نامه معمولی که پستچی داخل خانه می اندازد و فوراً میرود.

ریسمان اصلی هم چون کار خاصی ندارد و مدام صف پیغام ها را چک میکند در کسری از ثانیه پیام را پردازش و خودش مجزا این متد AddFoundSite را با پارامترهایی که در نامه(!) بوده اجرا میکند.



خب فرض میکنیم ریسمان اصلی ما الان بیکار شده و اومده BeginInvoke چیکار میکنه؟ ( مخصوصا پارامتر هاشو من درک نمیکنم) دوباره خود AddFoundSite رو احظار میکنه ؟ یعنی یه حلقه میشه ؟

اگر ریسمان اصلی برنامه باشد، اصلاً هیچگاه if برقرار نمیشود و اصلاً ریسمان اصلی هیچگاه BeginInvoke را اجرا نمیکند.
اصلاً آن if برای فرق گذاشتن بین اجرای دستورات توسط ریسمان اصلی و سایرین بوده
اگر ان if نبود یک حلقه بینهایت میشد.



if چک میکنه اگه ریسمان اصلی ما فعلا کار داره یه درخواست(required) برای مراجعه به این قسمت

مجدد تاکید میکنم، مطلب فوق مشکل دارد.
InvokeRequired و BeginInvoke کاری که شلوغی و خلوتی و... ندارند! نان وایی که نیست !:31:

if-InvokeRequired ریسمان اصلی را از سایر ریسمانها تشخیص میدهد، همین و تمام!
BeginInvoke هم با هیچ چیز کاری ندارد یک پیغام برای اجرای Shortcut یک متد به انتهای صف کارهای ریسمان اصلی اضافه میکند. همین و تمام!



نباید ما کد رو به این صورت اصلاح کنیم

public void AddFoundSite(string site)
{
if (this.InvokeRequired)
{
this.Invoke(new OneTextDelegate(this.AddFoundSite), site);
return;
}
else
{
this.txtFoundSite.Text += site + "\r\n";
}
}

بله، این کد هم صحیح است، البته اگر else اضافه شود دیگر نیازی به return نیست.
در واقع return کد من و else کد شما یک عمل را انجام میدهند و وجود یکی از انها کافی است.
else را که میدانید چه میکند؟
return هم هر کجا اجرا شود، پایان اجرای دستورات تابع است و خط بعدی return دیگر اجرا نمیشود.
و در این کد نتیجه یکساینی با else میدهد.
اگر سایر ریسمان کد را اجرا کنند وارد if میشود و کارشان با return (در این محل) تمام میشود
اگر هم ریسمان اصلی اجرا کند که وارد if نمیشود و دستورات پس از ان را اجرا میکند.

کد داخل if همین و ثابت است ولی کد else میتواند بیشتر هم شود ... (مثل آن ListView) میتوان رنگ و فونت و متن و... چندین کنترلر را دستکاری کرد.
در اینجا مزیت کوچک return ان است که اصتلاحاً کدتان زیاد کوهان شتری و تودرتو نمیشود و کد زیبا تر و قابل فهم تری خواهید داشت.



در ضمن اگه این سولایی که من کردم به شئ گرایی ربطی داره ...

چندان ارتباطی ندارد ...
( البته تفاوت this و base در #C و یا Me و MyBase و MyClass در VB جزء مباحث جالب شی گرایی است و یا همان IList هم ... )

موفق باشید.

without_all
25-02-2010, 15:28
آقا آخرش فهمیدم (گرفتم :9:):26:
کد رو از دوباره خودن نوشتم و تمام قسمتاشو فهمیدم .
دست شما درد نکنه :40::11::11::42::35:

خیلی آقایی :10:

با تشکر
Woeful