:20: خیلی ممنون:11:
Printable View
:20: خیلی ممنون:11:
استثناء یا Exception : در vb.net به خطاهایی که در زمان اجرای برنامه (run time) رخ میدهند, استثناء گفته میشود.
برای مقابله و مدیریت استثناها در vb.net دو روش کلی وجود دارد :
روش ساخت نیافته که در vb6 روش پیش فرض است و روش ساخت یافته که در نسخه .net عرضه شده است.
روش ساخت نیافه Unstructureed error : در این روش برای مقابله با خطا از دستور On Error GoTo استفاده میکنیم :
On Error {GoTo [line | 0 | -1 ] | Resume Next}GoTo Line : کد مقابله با خطاء را که از خط line شروع میشود, فراخوانی میکند.
GoTo 0 : عملیات کنترل خطاء را در همان روال متوقف میکند, در واقع راهی برای خاموش کردن روشهای مقابله با خطاء است.
GoTo-1 : مشابه با بالا
Resume Next : وقتی خطایی اتفاق می افتد, اجرای برنامه را از دستور بعد از دستوری که موجب خطاء شده از سر می گیرد.
مثال :
در vb شی محصوص خطاء (Err) وجود دارد که برای برای مقابله بهتر با خطاها طراحی شده است.کد:
On Error GoTo handler
Dim num1 = 0, num2 = 100, result As Integer
result = num2 / num1
MsgBox(result)
Handler:
MsgBox("an Overflow err occurred")
3 خاصیت مهم سئ فوق عبارتند از :
Err.Number : که شماره خاص یک خطاء است (هر نوع خطایی دارای یک شماره منحصر به فرد است).
Err.Description : توضیح مختصری در مورد خطای اتفاق افتاده میدهد.
Err.Source : مقدار رشته ای برگشت میدهد که شئ با برنامه ایجاد کننده خطاء را مشخص میکند.(البته در برنامه های ما نام پروژه است اما برای کامپوننتهای Com خارجی میتواند مفید باشد).
شئ Err دارای متدی بنام Getexception است که با استفاده از آن میتوان یک شئ استثناء گرفت که نشان میدهد چه اتفاقی اقتاده است.
کد:
MsgBox(Err.Number & vbCrLf & Err.Description & vbCrLf & Err.Source)
کد:
یا
If Err.Number = n Thenیا
Do ………
End If
If (TypeOf Err.GetException() Is OverflowException) Then
Do ........
End If
دستور Resume :
با این دستور میتوان اجرای برنامه را بعد از وقوع خطاء از سر گرفت :
Resum : اجرای برنامه را از همان دستور که باعث خطاء شده از سر میگیرد.
Resum Next : اجرای برنامه را از دستور بعد از دستوری, که موجب خظاء شده از سر میگیرد.
Resum Line : برای از سر گیری برنامه به خطی که با برچسب line مشخص شده میرود.
On Error GoTo handler*** : در صورتیکه در ابتدای یک روال دستور On Error Resume Next را قرار بدهیم برنامه بدون توجه به خطاء از دستور بعد اجرا میشود
Handler:
Resume Next
anvar.net عزيز دست گلت در نكنه واقعاً عاليه خيلي خوب پيش ميره انشاء ا... خدا كمكت كنه
ميشه در مورد goto 0 و goto -1 بيشتر توضيح بدين ؟ :20:
مطالب خیلی جالبین... anvar.net هر وقت این فصل تموم شد (با اجازه شما) بگو مطالب رو پی دی اف کنم (البته با ذکر اسم شریف)
ا...ز زیاد :31:
ممنون از دوستان,آقای/؟ Shahrdar ؛ اجازه ما هم دست شماست, اختیار تام دارید.فعلا چند روزی صبر کن, مقدمات تمام میشه
چشم
:31: :31:
On Error GoTo |0|-1ارگومان صفر (0), در واقع تا زمانیکه On Error بعدی اجرا شود, رسیدگی به خطاء را در رویه مورد نظر به حالت تعلیق درمی آورد.
آرگومان 1 , رسیدگی به خطاء را در رویه مورد نظر به حالت تعلیق درمی آورد. به عبارتی خطاء را Nothing میکند.
اگر بخواهیم کد مقابله با خطاء را در یک روال غیر فعال کنیم میتوانیم از On Error GoTo 0 استفاده کنیم. استفاده از این دستور تمام اداره کننده های خطاء در روال جاری را غیر فعال میکند, توجه کنید که در صورتیکه خطایی رخ بدهد این عبارت از CLR نمی خواهد به یک خط با شماره خط 0 انتقال یابد (حتی در صورتیکه روال دارای یک خط با شماره صفر باشد ), استفاده از این کد این نتیجه را دربردارد که هیچ گونه کنترلی بر روی خطاهایی که رخ میدهند ندارید.
**** : غیر فعال سازی کد مفابله با خطاء با استفاده از دستور فوق نه تنها در روال فوق عمل میکند بلکه بطور کامل مقابله با خطاء به روش ساختاری را غیر فعال می سازد. یعنی قبل از اینکه خطاهای ایجاد شده بوسیله اداره کننده و نه CLR در برنامه بکار گرفته شوند باید اداره کننده های خطاء را فعال سازید.
اگر بخواهیم خطاهای ایجاد شده در یک روال را غیر فعال سازیم (یعنی خطاها را نادیده بگیریم) از عبارت On Error GoTo -1 استفاده میکنیم. این عبارت از CLR می خواهد خطاهای روال جاری و هر گونه روالی که CLR فراخوانی میکند و اداره کننده خطاء ندارند را نادیده بگیرد. در واقع CLR اقدام به پاکسازی خطاء میکند, در صورتیکه از این دستور استفاده کنیم اداره کننده خطاء فقط برای روال جاری معتبر است, زیرا پس از اتمام روال, اداره نمودن خطاء به وضعیت معمول خود بازمی گردد.
سلام بر جماعت شیفتگان VB (آخرین ورژن!)
ما هم دوباره برگشتیم و فعلاً دوباره برای فضولی در خدمت هستیم!!!!! :31:
با اجازه دوست عزیزم کاربر anvar.net، میگویم بروبچ این On Error را زیاد تحویل نگیرند، بلد باشید چگونه کار میکند و از آن باید چطور استفاده کرد ولی زیاد استفاده نکنید!!! کمی دندان برروی جگر شفیقتان بگذارید تا دوستمان دستور جدید Try Catch را توضیح دهند، آنوقت تا دلتان خواست مدام Try Catch تایپ کنید.! :10:
ممنون بسيار عالي و کامل بود :11:
لطفاً مسئولان سایت بگن من چطور میتونم این پست رو حذف کنم؟
دوستان خوب سلام
من تازه میخوام با VB.net کارکنم و تازه شروع کردم از آقای H2 که این سایت رو معرفی کردن متشکرم از ارسال آموزشهای اين سايت هم بسيار سپاسگذارم
سلام
عضویتتان را در سایت تبریک میگم! :10::10::10::10::10::10:نقل قول:
لطفاً مسئولان سایت بگن من چطور میتونم این پست رو حذف کنم؟
لطفاً مسئولان سایت بگن من چطور میتونم این پست رو حذف کنم؟
اقايون شرمنده سرم خيلي شلوغه.
امشب سعي ميكنم اين بحث رو تموم كنم. زياد عجله نكنيد
به دوستان شفیق پیشنهاد میکنم برخی جملاترا دیگه بکار نبرند و تا کاربر anvar.net همه مان را از تاپیکشان پرت نکرده بیرون دیگه تاپیک شان را بیشتر از این خراب نکنیم!!!! :31:
با اجازه کاربر anvar.net ! قصد فضولی ندارم و اصلاً حوصله تایپ هم ندارم! ولی گفتم کمکی کرده باشم و صرفاً خارج از گود نگویم لنگش کن!
امیدوارم زودتر این پست را ببینید و مطلب دیگری آماده کنید! اگر شما هم در مورد Try نوشتید، خوب باز میگذارید، دو سری توضیح کامل در مورد try خواهیم داشت
در نتیجه با آجازه شما متن زیر را ببرای دستور Try آماده کردم، امیدوارم فایده داشته باشد و مطلبی هرچند کوچک ولی جدید به دانسته های عظیم دوستان بیافزاید.
---------------------------------------------------------------
دستور Try:
این دستور برای هندلینگ خطاها و انجام عمل مورد نظر در قبال خطایی خاص است، خطاها اگر هندلر نشوند موجب Runtime Error در برنامه نهایی میشوند.
ولی در کل همیشه بهتر است تا از بروز خطا جلوگیری شود، چون اتفاق افتادن خطا و هندلینگ آن کاری پر هزینه است و باعث کاهش سرعت و کارآیی برنامه نهایی میشود.
مثلاً وقتی که متغییر شی ای دارید که احتمال هم دارد خالی یا Null یا همان Nothing باشد،
یک راه این است که بدون توجه به مقدار ان از این متغییر استفاده کنیم و بگوییم اگر Nothing باشد فوقش خطایی به وجود می آید که آن را هم هندلر خواهیم کرد.
ولی این تفکر جالبی نیست!
بهنتر است در یک If در اول استفاده چک شود و اگر متغییر مورد نظر Nothing نبود دستورات مورد نظر را انجام دهیم.
در کل مجدداً تکرار میکنم که اغلب اوقات پیشگیری بهتر از درمان است.
سینتکس کلی:
دستورات شما بعد از Try قرار میگیرند، اگر خطایی رخ دهد مابقی دستورات دیگر اجرا نخواهد شد و پرشی خواهیم داشت به اولین بلوک Catch ای که با نوع خطای مورد نظر هماهنگی داشته باشد (توضیح بیشتر خواهم داد! فعلاً این را در نظر بگیرید که بلوک های متعدد Catch چیزی مثل ساختار Select Case عمل میکنند)یعنی به محض اینکه خطا با اولین بلوک مچ شود همان بلوک اجرا میشود و از کلیه بلوک های دیگر صرف نظر خواهد شد.کد:Try
'commands
[Catch variant As Exception1 [When boolean]]
'commands for Exception1 type
[Catch variant As Exception2 [When i > 0]]
'commands for Exception1 type
[Catch variant As Exception3 [When i > 0]]
'commands for Exception1 type
[Finally]
'allways commands
End Try
اگر خطای اتفاق افتاده با هیچ یک از بلوک های Catch مچ نشود، هندلینگ نخواهیم داشت و خطا به سلسله مراتب بالاتر در فراخانی ارسال میشود تا شاید در آنجا هندلر شود و الی آخر ... ( که من به آن میگویم بالا رفتن حبابی!) و اگر به منبع اصلی فراخانی برسد و هنوز هندلر نشده باشد موجب Runtime Error و توقف برنامه شما خواهد شد.
بلوک Finally اگر استفاده شود، تضمین میکند که در هر شرایطی بدون توجه به وقوع خطا - عدم وقوع خطا - اجرا شدن دستورات خروج سریع از قبیل Exit Sub و Exit Function و حتی دستور زیبا و جدید Return ، باز هم در هر شرایطی بلوک بعد از Finally اجرا خواهد شد.
از این بلوک میتوانید برای آزادسازی منابع-بستن ارتباطها-بستن فایلها و... استفاده کنید.
(البته نباید این بلوک را جایگزین دستور جدید و فوق العاده قوی Using کرد.)
------------------------------------------------------------
VB8 برخلاف VB6 به شدت شی گراست و همه چیز با قوانین OOP و پلی مورفیزم اداره میشوند، در این راستا برخلاف VB6 که خطاها ماهیتی عددی داشتند و هر خطا با عددی خاص تایین میشد، اینجا در VB8 خطا ها ماهیتی Class ای دارند و هر خطا خود یا کلاسس ماژول است!!!
هر کلاسس ماژول خطا در دات نت وراثتی است از کلاسس Sysytem.Exception و شما هم میتوانید برای خود خطاهاتی سفارشی درست کنید (وچه بهتر که وراثتی باشد از همان کلاسس) فعلاً کاری با چگونگی به وجود آوردن خطای سفارشی نداریم و بحث بر سر رفع آن است!
بلوکهای Catch هم بر اساس کلاس و وراثت کار میکنند!
شما در بلوک Catch یک متغییر به عنوان نماینده خود تعریف میکنید (معمولاً با نام ex)که پس از هندلینگ خطا، شی کلاس خطای مورد نظر درون این متغییر ریخته میشود و تحویل بلوک کد درون Catch شما خواهد شد، این متغییر که حالا حاوی شی خطاست دارای اطلاعات محل و موقعیت و پیغام خطا و... میباشد که اطلاعات دقیق تری به شما و کاربر شما در مورد خطای مورد نظر میدهد.
اینکه کدام بلوک Catch با نوع متغییری که تعریف کرده میتواند خطا را هندلر کند طبق قوانین وراثت است.
نمیخواهم در این پست آموزش مبانی OOP و Polymorphism را بدهم ولی با اجازه اساتید اشاره ای مختصر میکنم:
درخت کاج<-درخت<-گیاه<-جاندار<-ماده و جسم<-چیز و وجود!
هر "درخت کاجی" وراثتی است از "درخت" و هر "درخت" وراثتی است از "گیاه" و...
هر درخت کاجی حتماً یک درخت و یا یک گیاه است!
ولی هر "درختی"، "درخت کاج" نیست!
و هر "گیاهی" هم "درخت کاج" نیست!
همین مسئله در کلاسس های وراثتی هم صادق است!
اگر شما متغییری از نوع "درخت" تعریف کنید میتوانید تمام انواع درخت را در آن جای دهید و
اگر متغییری از نوع "گیاه" تعریف کنید میتوانید علاوه بر تمام درختها تمام گیاه های دیگر را هم در آن جای دهید.
(ریشه ای ترین کلاسس در محیط دات نت کلاسس Object است و هر چیزی را که در دات نت با آن سروکار دارید به صورت مستقیم و غیر مستقیم با چند پله فاصله وراثتی است از نوع Object و درست به همین علت است که وقتی متغییری از نوع Object دارید میتوانید در آن هرچیزی بریزید.)
مثلاً بلاک زیر:
Catch ex As System.IO.DirectoryNotFoundException
میتوانید خطای ناشی از وجود نداشتن پوشه را هندلر کند.
مثلا وقتی دستور پاک کردن فایلی را داده اید ولی اتصلاً پوشه مورد نظر وجود ندارد، خطای فوق اتفاق می افتد.
ولی کلاسس System.IO.DirectoryNotFoundException وراثتی است از کلاسس System.IO.IOException و این هم وراثتی است از کلاسس اصلی System.Exception
در نتیجه اگر خطای DirectoryNotFound اتفاق بیافتد، هر یک از سه بلوک زیر میتوانند خطای مورد نظر را هندلر کنند:
Catch ex As System.IO.DirectoryNotFoundException
Catch ex As System.IO.IOException
Catch ex As System.Exception
و هر سه نوع کد فوق در هندلینگ خطای DirectoryNotFound هیچ فرقی با هم نخواهند داشت و اگر هم هر سه Catch فوق را داشته باشیم اینکه کدامشان خطای DirectoryNotFound را هندلر خواهند کرد صرفا به این ربط دارد که کدام بلوک Catch بالاتر قرار دارد، یعنی مثل ساختار Select Case ، هر کدام که بالاتر باشد خطای DirectoryNotFound را هندلر میکند و بقیه بلوک ها اجرا نمیشود.
درکش راحت است!
یک "درخت کاج" همه اش، اصل وجودش، تمامش یک "درخت" است، به همان اندازه که
یک "درخت کاج" همه اش، اصل وجودش، تمامش یک "گیاه" است! سلسله مراتب وراثتی قابل تفکیک نیستند.
نتیجه اخلاقی آنکه اگر شما یک بلوک Catch ex As System.Exception در آخر بلاکها داشته باشید میتوانید تمام انواع خطاهای رخ داده در بلوک Try را هندلر کنید و نیز اگر یک بلوک فوق در اول بلوک های Catch داشته باشید همه خطا ها را هندلر میکند و مابقی بلوکهای Catch هیچ گاه اجرا نخواهند شد.
------------------------------------------------------------
نکات ریز باقی مانده!
هر ساختار Try باید حداقل یک بلوک Catch یا یک بلوک Finally داشته باشد و نیز طبیعی است که اگر بلوک Catch نداشته باشد هیچ خطایی را هندلر نمیکند.
تا اینجا همه مطالب برای زبان دوقولوی VB.Net یعنی C#.Net هم صادق بود، غیر از آن که بلوک ها در C#.Net با {} شروع و پایان می یابند ولی دستور When مختص VB.Net است و شما میتوانید مثل بلاک If Then با آن عمل کنید و علاوه بر نوع متغییر، شرطی برای ورود به Catch هم تایین کنید.
مطلب آخر آنکه که هندلینگ فقط در بعد از دستور Try وجود خواهد داشت! (خود بلوک Try) یعنی اگر کد شما در محل بلاکهای Catch یا بلاک Finally مجدداً باعث بروز خطا شود، این خودش خطایی جدید است و سلسله مراتب بالارفتن حبابی را طی خواهد کرد. ولی Try-Catch تودرتو به هر شکل مجاز است!
در جوار دات نت جون خوش بگذره! :10:
ممنون _H2_ عزيز .
مثل هميشه کامل و دقيق بود.
اميدوارم شما و Avant عزيز به ارائه مطالب مفيدتون ادامه بدين :20:
چند تا سوال داشتم
__________________________________________________ ________________________________
اولي اينه که کلا منظور از Handle و Handling چيه ؟ يه چيزايي مبهم ميدونم ولي واسم گنگه اگه يه کوچولو راهنماييم کني ممنون ميشم :11:
__________________________________________________ ________________________________
و دوميش :
ميشه در مورد دستور Using توضيح بدين ؟نقل قول:
(البته نباید این بلوک را جایگزین دستور جدید و فوق العاده قوی Using کرد.)
__________________________________________________ ________________________________
در حالاتي که خطا به ندرت پيش مياد مثلا کانکشن برقرار نشه ، بهتر نيست اين کار رو به پردازش استثناء واگذار کنيم ؟نقل قول:
مثلاً وقتی که متغییر شی ای دارید که احتمال هم دارد خالی یا Null یا همان Nothing باشد،
یک راه این است که بدون توجه به مقدار ان از این متغییر استفاده کنیم و بگوییم اگر Nothing باشد فوقش خطایی به وجود می آید که آن را هم هندلر خواهیم کرد.
ولی این تفکر جالبی نیست!
بهنتر است در یک If در اول استفاده چک شود و اگر متغییر مورد نظر Nothing نبود دستورات مورد نظر را انجام دهیم.
__________________________________________________ ________________________________
يعني اگه يک تابع رو فراخواني کنم که در اون تابع خطا رخ بده و در بلوک Try موبوط به اون خطاي مورد نظرم با هيچيک از خطاهاي مورد نظر بلوکهاي Catch مطابقت نداشته باشه ، پردازش خطا به دنبال بلوک Catch اي که با خطا مطابقت داره در روال فراخوان ميگرده ؟ (اگه اينطوره که اين دات نت خيلي با کلاسه !) حالا فرض کن پردازش استثنايي تو روال فراخوان نداشته باشيم (در روال فراخوان و روالهاي بالاتر) اونوقت خطا در نظر گرفته نميشه ديگه نه ؟نقل قول:
اگر خطای اتفاق افتاده با هیچ یک از بلوک های Catch مچ نشود، هندلینگ نخواهیم داشت و خطا به سلسله مراتب بالاتر در فراخانی ارسال میشود تا شاید در آنجا هندلر شود و الی آخر ... ( که من به آن میگویم بالا رفتن حبابی!) و اگر به منبع اصلی فراخانی برسد و هنوز هندلر نشده باشد موجب Runtime Error و توقف برنامه شما خواهد شد.
هندلینگ را من به معنی عمومی "قلاب کردن-تور انداختن" استفاده کردم! یک دفعه شما خطا را هندلر میکنید و یک دفعه رویداد را، مثلاً زمانی که رویداد Click را هندلر میکنیدنقل قول:
حالا بزارید از دست این Try راحت بشیم! دل انگیز بابا!نقل قول:
ولی مثل دستور Dim است ولی پایانه استفاده از شی با End Using مشخص میشود و فقط هم برای اشیایی قابل استفاده است که رابط نابودسازی را پیاده سازی کرده باشند.
تشخیصش با شماست! اگر مثل باز کردن کانکشن به ندرت پیش می آید یا مثلاً فقط یک بار قرار است کد اجرا شود استفاده از Try بهتر استنقل قول:
ولی اگر احتمال وقوعش زیاد است و نیز کد مثلاً در یک حلقه بارها و بارها تکرار میبشود یا در وب توسط هزاران کاربر همزمان اجرا میشود بهتر است دقت بیشتری کنید.
دقیقاً !!! که گقتم، من نامش را گذاشته ام بالارفتن حبابی!نقل قول:
پس چی! فکر کرده اید با چغندر قند طرف هستید!نقل قول:
اینن را هم گفتم! خطا به صورت سراسری اعلام میشود و موجب runtime Error و در نتیجه نمایش پنجره مربوطه و حتی در ورژن های گذشته موجب بسته شدن برنامه میشود.نقل قول:
تست کنید متوجه میشود
مثلاً در رویداد Form_Load بنویید
Dim i As Integer
i = 0
i = 0 \ i
و برنامه را کامپایل کنید و EXE اش را اجرا کنید، متوجه میشوید.
ممنون h2 جان بابت وقتي که براي پاسخ به سوالاتم گزاشتي :11:
H2 جان استاد گرامی به خاطر آموزش جالبت بی نهایت متشکرم.:11:
ولی ممکن یه راهنمایی کوچولو بکنی که چه طور میشه به کد خطای مورد نظر دست پیدا کرد؟
و در ضمن توی کجای MSDN میشه متن پیغام مربوط به هر کد خطا رو پیدا کرد؟:41:
یه سئوال دیگه هم داشتم که البته خیلی به دستور try ربط نداره ولی...
با چه تابعی میشه موقع بروز خطا صدای هشدار رو از بلنگوی موجود در کیس فعال کرد؟ منظورم چیزی به غیر از تابع Beep
هستش چون این تابع با اسپیکر کار میکنه یا شاید هم من بلد نیستم ازش استفاده کنم!!!!
سلام
دل انگیز جانً! همان متغیری که به عنوان نماینده تحویل گرفتن کلاسس خطا معرفی میکنید! یک کلاسس تحویل میگیرد که شامل کلیه اطلاعات لازم است! :31:نقل قول:
مثلاً اگر نام متغییر ex باشد آنگاه
ex.Message
پیغام خطا را میدهد
ex.StackTrace
اطلاعات پشته فراخانی ها تا محل خطا را میدهد
ex.Source
منبع خطا را میدهد
ex.InnerException
اگر خطاها حالت تودرتو و پله کانی داشته باشند و مثلاً یک خطا باعث بروز یک خطای دیگر شود و... این کلاسس خطای ریشه را میدهد که خود یک کلاسس خطا است!
ex.HelpLink
یک لینک توضیح در وب یا کامپیوتر شخصی که توضیح بیشتری در مورد خطا میدهد و شما را رهتنمایی میکند (در صورت وجود!)
و....
هر کلاسس خطا برحصب نوع میتواند اطلاعات بیشتری به شما بدهد ....
یک تابع API میشناختم! الآن حضور ذهن ندارم! و یادم نیست از اسپیکر استفاده میکرد یا بلندگوی مادر بورد؟!نقل قول:
میتوانم پیدایش کنم و تست کنم!
ولی بوق هایی که از اسپیکر پخش میشوند در صورت نصب نبودن کارت صوتی به صورت خودکار از مادر بورد پخش میشوند.
H2 عزيز باز هم سلام و باز هم دستت درد نكنه
ولي مشكل من با كارت صداي آن برده كه معمولاً نصب ميشه ولي تو خيلي از ادارات اسپيكري وجود نداره كه بشه ازش صدا پخش كرد .
اگه بتوني تابعي معرفي كني خيلي ممنون ميشم.
سلام
در VB.Net خط زیر را به سر ماژول کد نویسی خود اضافه کنید:
سپس میتوانید با دستوری مثل (Beep(400,1000 کار کنید، عدد اول فرکانس است و دومی زمان پخشکد:Public Declare Function Beep Lib "kernel32" (ByVal dwFreq As Integer, ByVal dwDuration As Integer) As Integer
اگر دقت کنید میتوانید ارگ هم بسازید! چون مهمترین معیار یعنی فرکانس را هم دارید.
H2 جان بازهم دستت درد نکنه و مثل همیشه گل کاشتی:10::11::31:
در ضمن ایده ساخت ارگ فکر جالبیه واسه تفریح بد نیست
آقای H2 ممنون, مثل همیشه جامع و کامل بود, من یه چزهایی تایپ کرده بودم که گرچه کامل نیست ولی گفتم بذارم بهتره.
یه سمپل گذاشتم ببین, جالبهنقل قول:
در ضمن ایده ساخت ارگ فکر جالبیه واسه تفریح بد نیست
[HTML]
http://www.bestsharing.com/files/ai4ZMJ3304351/MiniPiano.zip.html
[/HTML]
یه سمپل گذاشتم ببین, جالبهنقل قول:
در ضمن ایده ساخت ارگ فکر جالبیه واسه تفریح بد نیست
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
Try \ Catch
در روش ساختاری مقابله با استثناء از بلوکهای Try برای فعال کردن رسیدگی به استثناء استفاده میشود. یک بلوک Try متشکل از کلمه کلیدی Try است که بدنبال آن بلوک مربوط به استثناء قرار میگیرد. بلوک Try عباراتی را که میتوانند موجب استثناء شوند و عباراتی را که در صورت رخ دادن یک استثناء نباید اجرا شوند را در خود احاطه میکند, بلافاصله بعد از بلوک Try چند بلوک Catch قرار میگیرند (البته ممکن است هیچ بلوکی نیز وجود نداشته باشد). هر بلوک Catch تصریح کننده یک پارامتر استثناء است و نشان دهنده نوع استثنایی است که باید بلوک به آن رسیدگی کند. اگر پارامتر استثناء حاوی یک نام پارامتر اختیاری باشد, رسیدگی کننده Catch میتواند از آن پارامتر برای برقراری تعامل با یک شئ استثناء گرفتار شده استفاده کند.
بطور اختیاری میتوان از یک بلوک Catch بدون پارامتر استفاده کرد. در این صورت تمام استثناء ها گرفتار میشوند.
پس از بلوک Catch آخر, بلوک اختیاری Finally قرار میگیرد. این بلوک حاوی کدی است که صرفنظر از اینکه استثنائی رخ داده یا خیر همیشه اجرا میشود.
هنگامیکه متد فراخوانی شده در برنامه ای, یک استثناء تشخیص دهد یا اینکه CLR متوجه مشکلی شود, متد فوق یا خود CLR یک استثناء براه می اندازد. نقطه ای از کد برنامه که در آن استثناء رخ داده نقطه Throw نامیده میشود.
در صورتیکه در بلوک Try خطایی رخ دهد, بلوک به کار خود پایان داده و کنترل برنامه به اولین رسیدگی کننده Catch پس از بلوک Try منتقل میشود. پس از یافتن Catch مناسب با استثنای رخ داده, رسیدگی کننده های Catch باقی مانده در نظر گرفته نمیشوند. اگر هیچ استثنایی در یک بلوک Try رخ ندهد, CLR تمام بخشهای رسیدگی کننده به استثناء در بلوک فوق را کنار میگذارد و بعد از عبارت Try \ Catch اجرا میشود.
***** کردن استثناء ها :کد:
Try
دستورها
Catch
در صورت ایجاد استثناء چه؟
Finally
کدی که حتما اجرا میشود
End Try
برای گرفتن نوع استثناء ها میتوان متغیری از نوع Exception تعریف کرد سپس محتویات آنرا نمایش داد.
در دستور بالا متغیر ex تمام استثناء هایی که توسط بلوک Catch گرفته میشوند را در خود نگه میدارد. با استفاده از عبارت Type در هر بلوک Catch میتوان نوع خطایی که باید گرفته شود را مشخص کرد.کد:
Try
Catch ex As exception
Msgbox(ex.tostring)
Or
Msgbox(ex.message)
End try
Catch ex As System.IO.FileNotFoundExceptionبا استفاده از دستور when میتوان بیشتر خطاها را ***** کرد
Catch ex As نوع استثناء when متغیر=?هر دستور Try \ Catch میتواند یک دستور Finally نیز داشته باشد.اگر این بلوک وجود داشته باشد حتما اجرا میشود (حتی اگر هیچ خطایی رخ ندهد یا اینکه توسط دستور exit try از Try \ Catch خارج شده باشیم).
Or
…………………………. When Err.number=?
مثال : سرریز
کد:
Dim x As Integer = 5
Dim y As Integer = 0
Try
x /= y
Catch ex As Exception When y = 0
MsgBox(ex.ToString Finally
Beep()
End Try
دو کلاس مهم مشتق شده از کلاس مبنای System.Exception کلاسهای applicationexception و Systemexception هستند,
کلاس applicationexception یک کلاس مبناء است که برنامه نویس میتواند با بسط آن اقدام به ایجاد انواع داده استثناء با توجه به نیازهای برنامه خود بکند.
CLR اقدام به ایجاد Systemexceptionها میکند. این عمل میتواند در هر نقطه ای از اجرای برنامه رخ دهد. استثناءهای زمان اجرا از کلاس Systemexception مشتق میشوند. در واقع یکی از مزایای استفاده از سلسله مراتب کلاس استثناء این است که یک رسیدگی کننده Catch میتواند یک نوع خاصی از استثناء ها را گرفتار کند.
کلاس Exception
کلاس فوق دارای چند خصوصیت مهم است :
Message : این خاصیت پیغام خطایی مبنی بر یک شئ استثناء در خود ذخیره میکند. این پیغام میتواند پیغام پیش فرض با نوع استثناء یا پیغام تهیه شده باشد و با رخ دادن استثناء به سازنده شء Exception ارسال گردد.
Stacktraces : این خاصیت حاوی رشته ای است که نشاندهنده پشته فراخوانی متد میباشد. محیط اجرایی لیستی از تعداد فراخوانی های متد در خود نگهداری میکند. رشته Stack…. ارائه کننده لیست این متدها است که هنوز اجرای آنها در زمان رخ دادن استثناء به پایان نرسیده است.
Innerexception : بطور کلی از این خاصیت برای منحرف کردن شئ های استثناء گرفتار شده در کد استفاده میشود. (بیشتر در برنامه های کتابخانه کلاس استفاده میشود)
Helplink : مشخص کننده مکان فایل کمکی در ارتباط با مشکل رخ داده است. اگر چنین فایلی وجود نداشته باشد مقدار آن Nothing میشود.
Source : مشخص کننده نام برنامه ای است که در آن استثناء اتفاق افتاده است.
TargetSite : مشخص کننده متدی است که استثناء در آن رخ داده است.
GetBaseException : این متد با قابلیت تغییر, یک آدرس برای خطای اولیه که ایجاد شده است بازمیگرداند؛ یعنی خطایی که زنجیره ای از خطاها را باعث شده است. شئ بازگردانیده شده از نوع Exception است.
انواع خطاهای استاندارد
نوع خطاء Exception : نوع پایه Object : کلاس مبنا برای تمامی خطاها است
نوع خطاء SystemException : نوع پایه Exception : کلاس مبنا برای تمامی خطاهای ایجاد شده بوسیله CLR است.
نوع خطای IndexOutOfRange Exception : نوع پایه SystemException : زمانیکه اقدام به دسترسی به عنصری در یک آرایه میکنید که وجود ندارد این خطاء بوسیله CLR ایجاد میشود.
نوع خطای NullRefrence Exception : نوع پایه SystemException : در صورت اقدام به ارجاع به یک شئ بدون اعتبار این خطاء بوسیله CLR ایجاد میشود.
نوع خطای InValidOperation Exception : نوع پایه SystemException : این خطاء به وسیله متدی رخ میدهد که شئ متد در یک وضعیت بدون اعتبار است.
نوع خطای Argument Exception : یک نوع خطای کلاس مبنا برای تمامی خطاهای آرگومان است.
نوع خطای ArgumentNull Exception : نوع پایه ArgumentException : این خطاء زمانی بوسیله متدهای یک شئ رخ میدهد که یک مقدار Null برای یک آرگومان عرضه میکنید که این آرگومان اجازه نمیدهد آرگومان Nothing باشد.
نوع خطای ArgumentOutOfRange Exception : نوع پایه Argument Exception : زمانی بوسیله یک متد ایجاد میشود که یک یا چند آرگومان در محدوده معتبر قرار ندارند.
کلاسهای استثناء تعریف شده از سوی کاربر
در صورتیکه مایل به ایجاد انواع خاصی از کلاسهای باشیم که مشکلات خاص برنامه های ما را کنترل کنند میتوانیم استثناء های جدیدی تعریف کنیم. این استثناء ها بطور مستقیم یا غیر مستقیم از کلاس مبنای applicationexception مشتق میشوند.
استثناءهای تعریف شده از سوی کاربر باید :
از کلاس applicationexception بدست بیایند.
دارای یک نام کلاس باشند که در انتهای آن عبارت exception وجود داشته باشد و 3 سازنده در آن اعلان شود. 1 سازنده پیش فرض, 1 سازنده که یک آرگومان رشته ای (پیغام خطاء) دریافت کند و سازنده ای که یک آرگومان رشته ای و یک آرگومان exception (پیغام خطاء و شئ داخلی خطاء) دریافت نماید.
ایجاد خطای سیستم :
اگر بخواهیم یک خطای سیستم را شبیه سازی کنیم یکی از اعداد رزرو شده برای سیستم را استفاده میکنیم. یعنی باید متد Raise را با یکی از اعداد 0 و 512 فراخوانی کنیم.
در صورتیکه روال فوق را مقدار 5 فراخوانی کنیم, خطای Invalid Procedure Call Or Argument ایجاد میشود, این خطاء معمولا زمانی رخ میدهد که تعداد آرگومانهای غلط را به روال انتقال میدهیم.کد:
Public Sub RaiseSystemException(ByVal ExceptionNum As Integer)
Err.Raise(ExceptionNum)
End Sub
درصورتیکه بخواهیم یک خطاء ایجاد کنیم که خطای تعریف شده کاربری باشد, میتوان مقدار ثابت vbObjectError را به عدد خطاء اضافه کنیم.مقدار ثابت فوق -2147221504 است.
Err.Raise(vbObjectError + ExceptionNum)برای تعیین خطای تعریف شده توسط کاربر یا تشخیص خطاهای سیستم از خطای کاربری باید ثابت vbObjectError را از خصوصیت Number سئ Err کم کنیم.
در صورتیکه مقدار بدست آمده عددی بین 0 و 65535 باشد خطای فوق یک خطای تعریف شده توسط کاربر است در غیر اینصورت خطا یک خطای سیستم Vb است.
دستت درد نکنه Avant عزيز :11:
تا نصفه خوندم الان بايد برم بعد که برگشتم کامل ميخونم و سوالامو مثل هميشه ميفرستم :31::31:
سلام
گفتم مجدداً مقداری فضولی کنم و بحث خطا را ببندم! امیدوارم جنبه کمکش افزون باشد!
دستور Try و On Error برای گیر انداختن و رفع رجوع خطا است ولی چگونه میتوان یک خطا را پیش آورد؟
چرا باید برنامه نویس دستی خودش یک خطا به وجود آورد؟ مگر سری را که درد نمی کند ...؟!
جوابش میشود به همان علتی که کلاسس های خود دات نت خطا را به وجود می آورند! (خودم میدونم نمی خواد تشکر کنید خیلی جوابش کامل و جامع بود! :31:)
مثالی میزنم:
شما یک برنامه ساده محاسبه فاکتوریل نوشته اید و مثلاً آن را Dll کرده اید و به دوست شفیقتان برای استفاده تحویل داده اید! این دوست شفیق شما نامردی میکند و عدد منفی به ورودی تابع شما میدهد! (یاد آورم میشوم طبق قوانین شفیقانه زبان شیرین ریاضی فاکتوریل منفی تعریف نشده است) در نتیجه شما هم نامردی میکنید و در درون تابعات اگر عدد ورودی منفی بود یک خطای خوشکل و کاملاً به جا تحویلش میدهید.!
از شوخی گذشته معمولاً وقتی کدی مینویسید و کد شما در شرایط استاندارد مود نیازش استفاده نمیشود پسندیده است که شما خطایی مرتبط را به وجود آورید.
مثل همین فاکتوریل عدد منفی یا تابعی برای تبدیل تاریخ نوشته اید ولی استفاده کننده از کد شما عدد ماه را 13 میدهد! و....
از فلسفه وجودی که بگذریم شما میتوانید با کمک کلمه کلیدی Throw یک خطا را به وجود آوردید (برعکس Try که خطای به وجود امده را خفه میکرد!)
سینتکسش هم ساده است
Throw X
که X یک نمونه، وهله، (New شده) از کلاسس خطا است،
طبیعتاً هر کلاسسی موقع New شاید یک سری پارامتر از شما بگیرد که با کلاسس دیگر فرق دارد،
مثلاً کلاسس های خطا عموماً Message را میگیرند که با آن شما میتوانید پیغام توضیحی در مورد دلیل خطا را کاملاً به کنترلر در بیاوردید.
حتی میتوانید برای خطاهایی که در برنامه تان به وجود می آید و هیچ نمونه آماده ای در دات نت ندارند خودتان با وراثت از کلاسس System.Exception خطای سفارشی بسازید
مثلاً اگر من میخواستم تابع فاکتوریل را بنویسم این کد را مینوشتم:
در این مورد من از کلاسس خطای داخلی System.ArgumentOutOfRangeException استفاده کردم که مخصوص خطای خارج از محدوده بودن یکی از آرگومانهای ورودی است و آن عبارت String که به سازنده اش دادم یعنی "value" مخصوص این کلاسس خطا است و شامل نام پارامتر ورودی مشکل دار است، کلاسس فوق از این نام String ای برای ساخت پیغام خطا استاندارد استفاده میکند و متن پیغام میشود:کد:Public Shared Function Factorial(ByVal value As Integer) As Double
Select Case value
Case Is < 0
Throw New System.ArgumentOutOfRangeException("value")
Case Is > 170
Throw New System.OutOfMemoryException
Case 0, 1
Return 1.0#
End Select
'--------------------------------------------------
Dim ret As Double = 1.0#
Do
ret *= value
value -= 1
Loop While value > 1
Return ret
End Function
Specified argument was out of the range of valid values.
Parameter name: value
اگر در زمان New کردن کلاسس فوق من به جای "value" نام "AAA" را میدادم متن پیغام خطا میشد:
Specified argument was out of the range of valid values.
Parameter name: AAA
(این صرفاً برای نمونه بود و فقط مخصوص کلاسس مذکور است)
میتوان خطاهای تودرتوی پله ای نیز داشت، طوری که خطا خطای دیگر را سبب شود و همه به صورت ذنجیره وار حفظ شوند و...
سعی کنید کلاسس های خطای استاندارد و مخصوص پر استفاده را در دات نت بشناسید و در صورت نیاز به پرتاب یک خطا، از کلاسس با مسمایی برای این کار استفاده کنید (کاربر anvar.net در پست 69 خود لیست کلاسس های خطای معروف را آورده اند در نتیجه من دوباره کاری نمیکنم)
(تمام مطالب فوق برای C#.Net هم صادق است ولی در C#.Net کلمه کلیدی مورد نظر با حروف کوچک باید نوشته شود یعنی به شکل throw و در VB.Net فرقی ندارد ولی استانداردش با T بزرگ است)
حالا میگم یک حالی میدهد بعد از این همه صغرا و کبرا و قصه حسین کرد شبستری، یک نابغه کشف نشده ای بیاید و بگوید:
"من دستور Throw را درست مینویسم و New هم کرده و پارامترها را صحیح میدهم ولی نمیدانم چرا هر کاری میکنم باز کاپیوتر خطا می دهد!!!!" :18:
نتیجه اخلاقی آنکه این بار که با خطایی روبرو شدید به جای نگاه کردن به آن به چشم یک مزاحم، ببینید حرفش چیست و چه مطلبی را گوشزد میکند و علاوه بر اینها از چه نوع و چه کلاسسی است.
فکر کنم با پست های کاربر anvar.net و این پست مرجع خوبی در مورد خطا در دات نت نوشته شد!
در آخر اگر دوستان میبینند جسارتی میکنم و شوخی میکنم به صرف آن است که مطالب کسل کننده نشود و دوستان و سروران گرامی راحت تر و با حوصله بیشتری بتوانید جفنگیات مرا بخوانید! (شما به دل نگیرید برادر! حساب شده بید! :31:)
موفق و شاد و بدون خطا باشید. :10:
H2 و Avant عزيز خسته نباشيد
بسيار عالي بود بخصوص آخراي بحث H2 :31:
H2 جان باز هم مثل همیشه گل کاشی.
این ایجاد کردن یا همون پرتاب کردن خطاها چیز جالبیه باعث میشه بیشتر با خطاها آشنا بشیم.
ولی این مستر بیلی هم خیلی حالش خوش نیست آخه مگه آدم حالش بده که برای خودش سردرد درست کنه؟
دوستان این بحثها رو ادامه بدیم یا نه؟
البته اگه طالبش باشید فقط تکنیکها رو مگیم و از سخن پراکنی (فارسی را پاس بداریم!!!) پرهیز میکنیم.
منتظر جوابم........................................ ...............
بله لطف می کنید اگر ادامه بدید
من بالاخره از شمال برگشتم نميدونيد دوري از تكنولوژي چقدر سخت بود.
بگزريم انتظار داشتم بعد از دوماه دوري اينجا خيلي تغيير كرده باشه ولي ظاهراً ساير دوستان و اساتيد محترم هم مثل من رفته بودند مسافرت انشاء ا... هرچه زود تر بر ميگردند و به ادامه بحث مي پردازند كه ما خيلي بهش نياز داريم.
به هر حال از زحمات گذشته و آتي همه دوستاني كه سعي در به پا داشتن اين تاپيك داشته اند بينهايت تشكر ميكنم
سلام
با اجازه کاربر anvar.net، در یکی از پستها راجب دستور فوق صحبتی شد که من به بعداً پاسش دادم و این هم توضیح.
- - - - - - - - - - - - - - - - - - - - - - - - -
دستور Using بسیار شبیه دستور Dim است.
با این تفاوت که پایان استفاده شی را تایین میکند.
یعنی شی نمونه سازی شده شما با Using با تضمین 100% در هر شرایط در End Using نابود خواهد شد و اشاره گر مربوطه آزاد خواهد شد.
ولی استفاده از Using راه و رسمی دارد!
1- چون Using باید روی اشاره گر شی قفل کند، در نتیجه باید در همان خط اول شی نمونه سازی شود و پر شود و این امر را نمیتوان به خطوط بعد محول کرد و اصلاً اشاره گر شی در بدنه Using در حالت ReadOnly قرار دارد و نمیتوانید چیزی در آن بریزید.!
2- شی مورد نظر باید واسط نابودسازی را همراه داشته باشد (System.IDisposable) یعنی برای هر نوعی که واسط مذکور را شامل نشود نمیتوان از Using استفاده کرد.
فهمیدن آنکه شی مورد نظر واسط مذکور را پیاده سازی کرده یا نه هم بسیار راحت است، کافیست به Object Browse در منوی View مراجعه کنید (دوست قدیمی و قدرتمند شده VB کارها) Object Browse تمام اطلاعات یک کلاسس را به واضحی و دقت تمام در اختیارتان قرار میدهد و البته راه دیگری هم دارد، کافیست دستور Using را برای نوع مربوطه تایپ کنید، اگر نوع مربوطه واسط نابودسازی را پیاده سازی نکرده باشد، ویرایشگر قدرتمند VB.Net این امر را تشخیص میدهد و زیر دستوراتتان خطی میکشد، طوری که انگار دستورتان غلط املایی دارد!
طبق دو قانون فوق کدهای زیر ایراد دارند!
و کد صحیح اینها هستندکد:Using dbCon As System.Data.SqlClient.SqlConnection
dbCon = New System.Data.SqlClient.SqlConnection("CONNECTIONSTRING")
'...
End Using
Dim bmp As New System.Drawing.Bitmap(100, 100)
Using graphic As System.Drawing.Graphics
graphic = System.Drawing.Graphics.FromImage(bmp)
'...
End Using
Using str As String = "StringValue"
'...
End Using
باید توجه داشته باشید که هیچ چیز نمیتواند مانع اجرای End Using شود چه خطا و چه خروج نابهنگامکد:Using dbCon As New System.Data.SqlClient.SqlConnection("CONNECTIONSTRING")
'...
End Using
Dim bmp As New System.Drawing.Bitmap(100, 100)
Using graphic As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)
'...
End Using
Dim str As String = "StringValue"
'...
مثلاً در کد زیر هم باز End Using اجرا میشود!
در نتیجه اگر کسی کد زیر را بنویسید، گرچه از نظر دستوری صحیح است و قاعدتاً ایرادی ندارد ولی بسیار خنده دار و مسخره خواهد بود!کد:Using dbCon As New System.Data.SqlClient.SqlConnection("CONNECTIONSTRING")
'...
Return 'Or Exit Sub, Exit Function, Exit Property, Exit For, Exit Do, Exit Try, ...
'...
End Using
استفاده از Using به جای Dim عادت بسیار پسندیده ای است و به شدت مورد سفارش مایکروسافت استکد:Private Function FunctionName() As System.Data.SqlClient.SqlConnection
Using dbCon As New System.Data.SqlClient.SqlConnection("CONNECTIONSTRING")
'...
Return dbCon
'...
End Using
میتوان دو کد زیر را معادل دانست، گرچه کاملاً معادل نیستند ولی بسیار شبیه هم عمل خواهند کرد و فقط در یک تک مورد جزئی تفاوت دارند.
کد:Using obj As New DisposableTypeName
'...
End Using
Dim obj As DisposableTypeName
Try
obj = New DisposableTypeName()
'...
Finally
If obj IsNot Nothing Then
DirectCast(obj, System.IDisposable).Dispose() 'Or CType(obj, System.IDisposable).Dispose()
obj = Nothing
End If
End Try
امیدوارم توانسته باشم کار و هدف کلمه کلیدی فوق را خوب توضیح داده باشم و در آخر تمام موارد فوق در C#.Net نیز صادق است ولی یک کم تفاوت نوشتاری Syntax وجود دارد.
با عرض تشكر خدمت اساتيد عزيز .
ميشه اگه ممكنه بحث رو با صحبت در مورد برنامه نويسي شي گرا ادامه بديد(ببخشيد كه بي ادبي كردم).
ممنون از آقای H2 واسه بحثهای توپش
با اینکه من میخواستم واسه DirctX یا Xna مطالبی آماده کنم ولی باشه واسه برنامه نویسی شی گرا یک چیزهایی میذارم. البته صبر داشته باشنقل قول:
ميشه اگه ممكنه بحث رو با صحبت در مورد برنامه نويسي شي گرا ادامه بديد
زیاد سخت نگیر بچه ها خودی هستندنقل قول:
ببخشيد كه بي ادبي كردم
من هم خيلي دوست دارم درباره DirctX يه چيزهايي ياد بگيرم ولي هنوز با مفاهيم پايه مشكل دارم.