گفتگو هایی در باب سی شارپ

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنونم استاد علی
الان شما میگید که بخاطر پشتیبانی نکردنِ رایترها از incremental بکاپ و همچنین ساپورت کردن یه رایتر از differential بکاپ که اون هم مال sql هه ، نمیشه از بکاپ افزایشی استفاده کرد؟ (اون کدی که دادین)
مشکلات متد IVssBackupComponents.SetPreviousBackupStamp هم جداست .
منظورتون اینه؟
 
آخرین ویرایش:

the_king

مدیرکل انجمن
خیلی ممنونم استاد علی
الان شما میگید که بخاطر پشتیبانی نکردنِ رایترها از incremental بکاپ و همچنین ساپورت کردن یه رایتر از differential بکاپ که اون هم مال sql هه ، نمیشه از بکاپ افزایشی استفاده کرد؟ (اون کدی که دادین)
مشکلات متد IVssBackupComponents.SetPreviousBackupStamp هم جداست .
منظورتون اینه؟
مطمئن نیستم، اگه فرض رو بر این بذاریم که حتما باید از SetPreviousBackupStamp استفاده بشه و حتما باید یک writer در کدتون انتخاب بشه همینطوره و نمیشه همچین backup هایی رو گرفت. ولی اگه این فرض رو قبول کنیم این ابهام پیش میاد که برای backup گرفتن به شیوه full که writer ای انتخاب نکردید و کد هم بدون مشکل کار کرد و backup گرفت. چطور اونجا لازم نبود writer مشخص بشه و اینجا لازمه؟ این خودش ابهامه. اگه writer پیشفرضی وجود داره کدومه.

من اینطور به قضیه نگاه می کنم که به عنوان کد نویس فرضا حاضرم تمامی اون writer های ثبت شده روی سیستم رو داخل حلقه یکی یکی برای روتین و برای
SetPreviousBackupStamp امتحان کنم، بالاخره اگر writer ای لازم باشه، یکی از اون writer های سیستم خواهد بود. component های هر writer ای هم که در مشخصات writer ها معلومه. پس به نظر این قضیه رو میشه یجور حل کرد. اما مشکل اساسی از دید من انتخاب writer نیست. مشکل اساسی از دید من اینه که گیرم که یکی از writer ها رو امتحان کردم و کد به هر دلیلی بدون خطا کار کرد و backup ای هم گرفت، حالا از کجا بفهمم backup ئه full نیست و با قبلی ها فرق داره؟ و از کجا بفهمم به کدوم backup متصل شده؟ هیچ جایی که مشخصه ای در snapshot ها گزارش نمیده که backup ثبت شده full ئه یا نه. اینقدر که این مساله به نظر من مشکل محسوب میشه انتخاب writer مساله نیست.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام بر استاد علی.
خیلی ممنونم از توضیحات تون.
این یکی دو ماهی ، قبل عید ، کارهای شخصی را و بعد عید هم مسافرت و هم کارهای شخصی را رسیدم ، نتونستم ادامه بدم.

پس اولین مشکل اینه که نوع فایل بکاپ را نمیشه مشخص کرد؟
یه سئوال اینکه الان وقتی بکاپ کامل میگیریم ، فرضا دو تا بکاپ کامل گرفتیم از یک درایو . هر دوشون یک داده و فایلی ای را برای بکاپ گیری نشونه گذاشتن . حالا اون داده و فایل ، مثلا حذف شد و روی اون هم عمل write انجام شد پس vss اطلاعات شو میخواد کپی کنه . حالا چون دو تا snapshot از اون فایل داریم ، هر کدوم از snapshot ها ، یه بار از اون فایل ، کپی انجام میدن؟ یعنی در مجموع دو تا کپی از اون فایل حذف شده ، توسط snapshot ها انجام میشه؟
ممنون
 

the_king

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

پس اولین مشکل اینه که نوع فایل بکاپ را نمیشه مشخص کرد؟
یه سئوال اینکه الان وقتی بکاپ کامل میگیریم ، فرضا دو تا بکاپ کامل گرفتیم از یک درایو . هر دوشون یک داده و فایلی ای را برای بکاپ گیری نشونه گذاشتن . حالا اون داده و فایل ، مثلا حذف شد و روی اون هم عمل write انجام شد پس vss اطلاعات شو میخواد کپی کنه . حالا چون دو تا snapshot از اون فایل داریم ، هر کدوم از snapshot ها ، یه بار از اون فایل ، کپی انجام میدن؟ یعنی در مجموع دو تا کپی از اون فایل حذف شده ، توسط snapshot ها انجام میشه؟
ممنون
این مساله چون مربوط به پیاده سازی داخلی snapshot ها است و استاندارد باز ای هم در کار نیست، شیوه پیاده سازی مشخص و مستند نیست که جایی بررسی اش کنیم، ولی طبق روالی که رایجه و مایکروسافت هم در خیلی موارد اسفاده کرده، مواردی که میشه اشتراکی ثبت بشه رو در چند نسخه ثبت نمیکنن، چون بیخودی حجم backup زیاد میشه.
یعنی میتونه دو نسخه کپی باشه، شاید، ولی بعیده، حتما نیازی نیست که دو تا نسخه کپی بگیره، چون محل ذخیره سازی snapshot ها متفاوت نیست، یکجا است. میتونه یک نسخه رو بصورت اشتراکی بین دو یا بیشتر snapshot استفاده کنه و به اونها لینک اشتراکی بده و نسخه اشتراکی وقتی پاک میشه که همه snapshot های لینک شده بهش حذف شده باشن. احتمال اینجور پیاده سازی اشتراکی بیشتره.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
این مساله چون مربوط به پیاده سازی داخلی snapshot ها است و استاندارد باز ای هم در کار نیست، شیوه پیاده سازی مشخص و مستند نیست که جایی بررسی اش کنیم، ولی طبق روالی که رایجه و مایکروسافت هم در خیلی موارد اسفاده کرده، مواردی که میشه اشتراکی ثبت بشه رو در چند نسخه ثبت نمیکنن، چون بیخودی حجم backup زیاد میشه.
یعنی میتونه دو نسخه کپی باشه، شاید، ولی بعیده، حتما نیازی نیست که دو تا نسخه کپی بگیره، چون محل ذخیره سازی snapshot ها متفاوت نیست، یکجا است. میتونه یک نسخه رو بصورت اشتراکی بین دو یا بیشتر snapshot استفاده کنه و به اونها لینک اشتراکی بده و نسخه اشتراکی وقتی پاک میشه که همه snapshot های لینک شده بهش حذف شده باشن. احتمال اینجور پیاده سازی اشتراکی بیشتره.

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

the_king

مدیرکل انجمن
خیلی ممنون استاد علی
پس اگه احتمالا اشتراکی استفاده میشه ، فرق خاصی بین بکاپ افزایشی و کامل نباید باشه . درسته؟
چون بکاپ کامل هم هر چند تا باشه ، دوباره از اول کپی نمیکنه و اشتراکی هستن .
چرا، بالاخره اون snapshot ها فقط داده کلاستر ها رو که شامل نمیشن که اشتراکی باشن، سایر مشخصاتی مثل لیست فایل ها و تاریخ هم هست که هر snapshot مستقلا باید داشته باشه و نمیشه اشتراکی باشه.
backup افزایشی میتونه لااقل در شروع کار مشخصات کمتری داشته باشه تا یک backup کامل چون اطلاعاتش وابسته است به backup دیگری.
در ضمن شما هر وقت اراده کنید می توانید بین دو backup کامل یکی رو مستقلا حذف کنید و اتفاقی برای اون یکی نمی افته. ولی backup افزایشی زنجیره ارتباطی و وابستگی داره و نمی توانید backup کامل آغازین یا backup های افزایشی میانی رو حذف کنید و backup افزایشی آخر رو نگه دارید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد
خیلی ممنونم استاد علی .
یه تست سرپایی کردم ، احتمال میدم نظرتون درباره ی اشتراکی بودن داده های بکاپ درست باشه . بنابراین گرفتن بکاپ افزایشی و پیگیری اش برای سطح علمی من ، از دست دادن زمان و نتیجه شم معلوم نیست چی میشه .

الان میخوام ادامه ی بخش های دیگه ی پروژه رو برم . میخوام بخش نظارت بذارم . به این صورت که طرف توی تنظیمات نرم افزار ، میزان تغییرات برای هر درایو را بصورت جداگانه مشخص میکنه . مثلا مقدار 10 گیگ را برای درایو F مشخص میکنه . بعد نرم افزار از اون به بعد درایو را نظارت میکنه که حجم تغییراتش به 10 گیگ که رسید ، به کاربر پیام میده که حالا وقت گرفتن بکاپ از اون درایو هست (و اینکه بکاپ میگیره) . منظور از تغییرات هم یعنی اینکه مثلا طرف توی تنظیمات ، 10 گیگ را برای درایو F که مشخص کرد ؛ نرم افزار ، وضعیت و فایل های آخرین بکاپی که گرفته بود را در دسترس داره و لیست فایل هایی که آخرین بکاپ ، شامل شون میشد را نادیده میگیره . حالا 5 گیگ اطلاعات به درایو F اضافه میکنه . نرم افزار این 5 گیگ رو ثبت میکنه . بعد 3 گیگ از اطلاعات جدید را حذف میکنه (اطلاعاتی که جدیدا کپی کرد و شامل همین 5 گیگ اطلاعات اخیرا کپی شده در درایو بود . یعنی اطلاعاتی که بکاپ های قبلی شامل شون بوده ، نیست و اگه اطلاعاتی که درون بکاپ های قبلی شامل بشه را حذف کنه ، نرم افزار کاری نمیکنه) . بنابراین ، نرم افزار از اون 5 گیگ ، 3 گیگ را توی محاسباتش کم میکنه (میشه 2 گیگ) . و بعد هم به نظارتش ادامه میده تا این فاصله ی 8 گیگ اطلاعات پر بشه و کلا تغییرات به 10 گیگ که رسید ، نرم افزار بکاپ میگیره .

کلا بخش جدید و مهمترین کار نرم افزار ، الان اینه . یعنی میخوام وقتی عملی که باعث اضافه شدن اطلاعاتی در درایوی میشه را توی برنامه ام متوجه بشم (چه توسط copy-paste و چه توسط مثلا نصب نرم افزار و بازی در درایوی و چه اینکه نرم افزارهای دیگه ، عملیات کپی کردن اطلاعاتی را از درون خودشون انجام میدن) و هم وقتی که کاربر یا نرم افزار ، اطلاعاتی را میخواد حذف کنه ، متوجه بشم .
حالا خواستم ازتون بپرسم که برای این قضیه ، چجور راهکاری را برم بهتره؟ فقط راهکار میخوام . کد نمیخوام . چون به راهکارهای مختلف آشنا نیستم ، پرسیدم .
مثلا اینکه آیا مثل همون event viewer که توی پروژه ی قبلی گفته بودین ، مثل اون کلاسی هست که زمان کپی یا حذف اطلاعات ، مطلع مون کنه؟ اگه هست ، حالا وقتی برنامه ای اطلاعاتی را کپی یا حذف میکنه ، چجور باید متوجه بشم؟
یا مثلا راهکار این باشه که لیستی از اطلاعات ، زمان بکاپ گرفتن تهیه کنم (پس از این به بعد اطلاعاتی اضافه بشه ، ازش بکاپ گرفته نشد) و با کلاس هایی که موجود هستن و اطلاعات حجم استفاده شده ی درایو را میدن ؛ توی تایمری ، مثلا هر 1 دقیقه ، مدام حجم درایو استفاده شده را بگیرم و اگه این حجم درایو ، تغییری کرد ، پس مشخص میشه که اطلاعاتی بهش اضافه یا کم شد . اما به هر حال ، وقتی که فایلی حذف بشه ، باید جستجو کرد تا متوجه شد فایلی که حذف شده ، توی لیست بکاپ قبلی موجود بوده یا نه (فایلی حذف شده که جدید بوده و توی لیست بکاپ ها نبوده تا نرم افزار در این صورت اون مقدار از اطلاعات را برای کم کردن ، محاسبه کنه . مثل قضیه ی همون 3 گیگ اطلاعات). بنابراین ، جستجو کردن برای پیدا کردن این فایل ها باز خودش سربار زیادی روی پردازنده و مخصوصا هارد میذاره چون هر بار بعد از کم شدن اطلاعات از درایو ، باید کل اطلاعات موجود در اون هارد جستجو و با اطلاعات پایگاه داده ی نرم افزار ، مقایسه بشه .

خیلی ممنون . ببخشید طولانی شدها . :rose:
 

the_king

مدیرکل انجمن
الان میخوام ادامه ی بخش های دیگه ی پروژه رو برم . میخوام بخش نظارت بذارم . به این صورت که طرف توی تنظیمات نرم افزار ، میزان تغییرات برای هر درایو را بصورت جداگانه مشخص میکنه . مثلا مقدار 10 گیگ را برای درایو F مشخص میکنه . بعد نرم افزار از اون به بعد درایو را نظارت میکنه که حجم تغییراتش به 10 گیگ که رسید ، به کاربر پیام میده که حالا وقت گرفتن بکاپ از اون درایو هست (و اینکه بکاپ میگیره) . منظور از تغییرات هم یعنی اینکه مثلا طرف توی تنظیمات ، 10 گیگ را برای درایو F که مشخص کرد ؛ نرم افزار ، وضعیت و فایل های آخرین بکاپی که گرفته بود را در دسترس داره و لیست فایل هایی که آخرین بکاپ ، شامل شون میشد را نادیده میگیره . حالا 5 گیگ اطلاعات به درایو F اضافه میکنه . نرم افزار این 5 گیگ رو ثبت میکنه . بعد 3 گیگ از اطلاعات جدید را حذف میکنه (اطلاعاتی که جدیدا کپی کرد و شامل همین 5 گیگ اطلاعات اخیرا کپی شده در درایو بود . یعنی اطلاعاتی که بکاپ های قبلی شامل شون بوده ، نیست و اگه اطلاعاتی که درون بکاپ های قبلی شامل بشه را حذف کنه ، نرم افزار کاری نمیکنه) . بنابراین ، نرم افزار از اون 5 گیگ ، 3 گیگ را توی محاسباتش کم میکنه (میشه 2 گیگ) . و بعد هم به نظارتش ادامه میده تا این فاصله ی 8 گیگ اطلاعات پر بشه و کلا تغییرات به 10 گیگ که رسید ، نرم افزار بکاپ میگیره .
قبلا هم در این مورد گفتید و نظر و میشنهادم رو گفتم و تکرارش هم نمیکنم. چیزی هم که میگید نه عملی است و نه منطقی و نه کارآمد. در ضمن حرفاتون طوریه که انگار در مورد هر backup ای حرف میزنید جز snapshot های vss. اگر اطلاعاتی دارید که ۲ گیگابایت تغییرات داشته، دو حالت بیشتر نداره. یا از اون تغییرات راضی هستید یا بعدا ازشون پشیمون میشید. اگر راضی هستید که backup ای که الان بگیرید شامل تغییرات در آینده میشه، نه ۲ گیگ در گذشته و به حجم تغییرات در گذشته ابدا ربطی نداره. پس حجم backup اش هم ربطی به تغییرات در گذشته نداره. اگر هم بعدا پشیمون میشید که دیگه پشیمونی سودی نداره چون تازه میخواهید backup بگیرید و برای اینکار دیر شده. هر وقت هم بلای سخت افزاری سر درایو بیاد backup ئه بدردتون نمیخوره چه ۱۰ مگابایت و چه ۱۰ گیگابایت.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
قبلا هم در این مورد گفتید و نظر و میشنهادم رو گفتم و تکرارش هم نمیکنم. چیزی هم که میگید نه عملی است و نه منطقی و نه کارآمد. در ضمن حرفاتون طوریه که انگار در مورد هر backup ای حرف میزنید جز snapshot های vss. اگر اطلاعاتی دارید که ۲ گیگابایت تغییرات داشته، دو حالت بیشتر نداره. یا از اون تغییرات راضی هستید یا بعدا ازشون پشیمون میشید. اگر راضی هستید که backup ای که الان بگیرید شامل تغییرات در آینده میشه، نه ۲ گیگ در گذشته و به حجم تغییرات در گذشته ابدا ربطی نداره. پس حجم backup اش هم ربطی به تغییرات در گذشته نداره. اگر هم بعدا پشیمون میشید که دیگه پشیمونی سودی نداره چون تازه میخواهید backup بگیرید و برای اینکار دیر شده. هر وقت هم بلای سخت افزاری سر درایو بیاد backup ئه بدردتون نمیخوره چه ۱۰ مگابایت و چه ۱۰ گیگابایت.

خیلی ممنون استاد علی
آخه قبلا مفصل پرداخته نشد و جواب دقیقی نگرفتم . الان هم دقیقا متوجه ی منظور دقیق تون نشدم . حس میکنم شما مطلبم رو خوب متوجه نشدین چی شد و این جواب را دادین . به نظرم منطقی هست برای بکاپ گیری . چرا میگید نیست؟ البته کارآمد شاید نباشه و عمده ی دلیل اش هم مصرف زمان زیاد و درگیری هارد برای جستجوی اطلاعات خواهد بود. واسه همین هم این سئوال را پرسیدم.

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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
من روشی که برای همون راهکارم پیدا کردم (راهکارم همون جستجوی کل فایل ها در درایو هست و راهکار دیگه ای پیدا نکردم) ، اینه که از کلاس parallel برای foreach استفاده کنم (parallel.foreach) :

Fastest way searching specific files

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

استاد علی ، احیانا ، لینک زیر که به کار من (سریعترین روش جستجو در فایل ها و پوشه های یک درایو) ، آیا ربطی داره؟ :

http://myblogs.avisikta.com/lucene-net-full-text-search-engine-net-application/

این احتمالا داره روش جستجو در متن را میگه که با regex در سی شارپ هم میشه انجام داد. درسته؟
 

the_king

مدیرکل انجمن
شما راهکارتون رو با چه معیاری سنجیدید؟ کدوم سناریو ها؟ من سه تا سناریو بهتون گفتم. شما یا باید میگفتید اشتباه میکنم و راهکار من برای فلان سناریو که گفتی اینطور رفتار میکنه یا میگفتید اینها قبول ولی سی چهل تا سناریو دیگه هست که اینطوریه و اونطوریه و براش درست کار میکنه.
هر اتفاقی که میتونه برای سیستم کاربر بیافته و هر تغییراتی که روی درایو رخ میده و هر نیازی که کاربر خواهد داشت رو لیست میکنید، از ترکیب شون سناریو های کاملا متفاوت میسازید و بعد بررسی میکنید این ایده و راهکاری که من دارم برای سناریو ۱ چه نتیجه ای داره و برای سناریو ۲ چه نتیجه ای و ...
و طبعا اگه دیدید از ۲۰ سناریو برای ۵ تاش هم مفید نیست باید بذاریدش کنار. نه اینکه یهو برید سر پیاده سازی.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
استاد علی ، وقتی شی ای از FileSystemWatcher درست میکنم و موقعی که Delete اتفاق میافته ، وقتی آیتمی را از یه درایو ، بصورت عادی حذف میکنم (به recycle bin منتقل میشه) ، مقدار e.FullPath در این رویداد Delete ، مسیر کامل فایل حذف شده را میده . اما وقتی همون فایل را دوباره از recycle bin حذف میکنیم ، مقدار e.FullPath ، مسیر را میده اما برابر با نامی که قبلا اسمش بود ، نیست . (مسیرش را نمیگم ها . خوب معلومه مسیرش را باید از توی پوشه ی recycle bin بده . اما اون آیتم حذف شده برابر با نامی که در سرمنشاء اش بود ، نیست) .

نمیشه کاری کرد که متوجه شد زمان حذف شدن یه آیتم از recycle bin ، نام سر منشاء اش چی بود؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
بعد اینکه استاد علی ، بعد از اینکه بکاپ گرفتیم ، رویداد اینکه بکاپ موفقیت آمیز تهیه شد یا نه ، متد CVssWriter::OnBackupComplete هست؟
آخه یه متد دیگه هست بنام IVssBackupComponents::BackupComplete که توضیحات شون خیلی شبیه هم هست . ولی من حس میکنم (با توجه به توضیحات و ...) متد CVssWriter::OnBackupComplete ، همون کار رویداد اتمام موفقیت آمیز بکاپ باشه . درسته؟
رویداد OnPostSnapshot هم که مال یه مرحله قبل تر از OnBackupComplete هه . درسته؟ یعنی بهترین رویداد ، همین OnBackupComplete هه. درسته؟
رویداد OnBackupShutdown هم مال وقتی هه که موقع بکاپ گیری مشکلی بوجود اومد و کلا بکاپ با شکست مواجه شد . درسته؟
 

the_king

مدیرکل انجمن
استاد علی ، وقتی شی ای از FileSystemWatcher درست میکنم و موقعی که Delete اتفاق میافته ، وقتی آیتمی را از یه درایو ، بصورت عادی حذف میکنم (به recycle bin منتقل میشه) ، مقدار e.FullPath در این رویداد Delete ، مسیر کامل فایل حذف شده را میده . اما وقتی همون فایل را دوباره از recycle bin حذف میکنیم ، مقدار e.FullPath ، مسیر را میده اما برابر با نامی که قبلا اسمش بود ، نیست . (مسیرش را نمیگم ها . خوب معلومه مسیرش را باید از توی پوشه ی recycle bin بده . اما اون آیتم حذف شده برابر با نامی که در سرمنشاء اش بود ، نیست) .

نمیشه کاری کرد که متوجه شد زمان حذف شدن یه آیتم از recycle bin ، نام سر منشاء اش چی بود؟
با روش کار recycle bin جور در نمیاد. شما ممکنه بارها فایلی به نام C:\my.log رو ایجاد کنید و حذف کنید و به سطل آشغال بفرستید، داخل سطل آشغال باید همه اون فایل های my.log موجود باشند. پس بخاطر تشابه اسامی تغییر نام یا مسیر اجتناب ناپذیره. البته از نظر فنی recycle bin پیشفرض میتونه با یک سرویس دیگه از هر شرکتی جایگزین بشه (مثل سرویس هایی که symantec جایگزین سطل آشغال میکنه) که مساله رو از این که هست هم پیچیده تر میکنه.
منظورم اینه که اگر برای recycle bin هم راهکاری پیدا کنید، لزوما برای همه کاربر ها جواب نمیده.
از طرف دیگه FileSystemWatcher دقیقا داره رخداد درست رو گزارش میکنه، کاری نداره که محتویات فلان پوشه در Explorer طور خاصی تفسیر میشه یا نه. محتویات Recycle bin مثل سایر پوشه های خاص ویندوز بصورت اختصاصی تفسیر و نمایش داده میشه. اما چون FileSystemWatcher کارش یک گزارش سطح پایینه و صرفا دید File System ای داره، کاری با این تفاسیر سطح بالای Explorer ویندوز نداره.
 

the_king

مدیرکل انجمن
بعد اینکه استاد علی ، بعد از اینکه بکاپ گرفتیم ، رویداد اینکه بکاپ موفقیت آمیز تهیه شد یا نه ، متد CVssWriter::OnBackupComplete هست؟
آخه یه متد دیگه هست بنام IVssBackupComponents::BackupComplete که توضیحات شون خیلی شبیه هم هست . ولی من حس میکنم (با توجه به توضیحات و ...) متد CVssWriter::OnBackupComplete ، همون کار رویداد اتمام موفقیت آمیز بکاپ باشه . درسته؟
این در واقع کلاس شما است که اعلام می کنه کی Backup تموم میشه، مثلا کلاس های عادی #C ئه. رخداد های داخل کلاس برای اطلاع خارج از محیط کلاس هستند، نه داخل کلاس.
BackupComplete یک رخداد ئه و OnBackupComplete متدی که اون رخداد رو بوجود میاره، دقیقا همونطور که Form.Load یک رخداد ئه و Form.OnLoad متد ایجاد کننده رخداد Load. شما وقتی دارید یک کلاس #C رو طراحی می کنید که وارث کلاس دیگری مثل Form هست، یکسری رخداد برای خارج از اون کلاس به ارث بردید، مثل Form.Load که عملیات پیشفرض برای رخ دادن رخدادش در Form در متد Form.OnLoad قرار داره که قابل گرانبار کردن هستند. شما اگر دلتون خواست این متد OnLoad رو گرانبار می کنید و دلتون نخواست نمی کنید تا همون روال پیشفرض اش رو انجام بده. این متد OnLoad ئه که موجب رخ دادن Load میشه، وگرنه Load خود به خود اتفاق نمی افته. اگر شما کد های داخل OnLoad رو از کار بندازید هیچوقت Load ای رخ نمیده چون هر جا لازم باشه Load رخ بده OnLoad فراخوانی میشه.
کسی هم که میخواد از این کلاس شما استفاده کنه، متد دلخواه اش رو به Form.Load متصل می کنه تا بفهمه کی Load میشه. داخل کلاس هر زمان قراره رخداد Load اتفاق بیافته متد OnLoad اجرا میشه تا با پارامتر های مناسب متد متصل شده به کاربر کلاس اجرا بشه. شما می توانید در OnLoad چیزی به این روال اضافه کنید یا تغییر بدید یا اصلا از کار بندازیدش.
در مورد BackupComplete هم همینطوره. هیچ BackupComplete ای رخ نمیده مگر اینکه OnBackupComplete اجرا بشه. حالا دلتون خواست در OnBackupComplete تفییری می دهید و دلتان نخواست نمی دهید.
و برای چندمین بار میگم، رخداد ها برای استفاده در خارج از کلاس هستند، نه داخل خود کلاسش. شما اگر دارید داخل کلاسی کد می نویسید با OnBackupComplete به ارث رسیده اش کار می کنید ولی BackupComplete برای استفاده بیرون از کلاس ئه، نه داخل کلاس. شما هیچوقت رخداد داخل یک کلاس رو به کدی داخل خودش متصل نمی کنید چون قبل از اینکه رخداد رخ بده خودتون در جریانش قرار گرفته اید.

رویداد OnPostSnapshot هم که مال یه مرحله قبل تر از OnBackupComplete هه . درسته؟ یعنی بهترین رویداد ، همین OnBackupComplete هه. درسته؟
OnPostSnapshot رویداد نیست. متد فراخوان رویداد ئه. مرحله اش هم معلوم نیست چند مرحله قبل تر ئه، لزومی نداره یک مرحله عقبتر باشه، میتونه دو مرحله یا سه مرحله عقبتر باشه.
بهترین رویداد هم نمی دونم به چی میگید. ملاکی که برای بهترین و بدترین دارید رو نمی دونم.

رویداد OnBackupShutdown هم مال وقتی هه که موقع بکاپ گیری مشکلی بوجود اومد و کلا بکاپ با شکست مواجه شد . درسته؟
خیر. وقتی برنامه یا سرویس ای Shutdown میشه الزاما معنی اش این نیست که مشکلی پیش اومده. چه زمانی که مشکلی پیش اومده و چه زمانی که مشکلی پیش نیومده می توانید و توقع میره که همچین رخدادی رو داشته باشید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنونم استاد علی بابت هر دو جواب :rose:
هر چند توی alphavss ، متد IVssBackupComponents.BackupComplete را داریم اما فکر نکنم این متد در اونجا برابر با همین نام از متد در توضیحات مایکروسافت باشه چون اون ورودی دریافت میکنه اما این نمیکنه . احتمالا متد IVssBackupComponents.BeginBackupComplete در alphavss برابر با متد IVssBackupComponents::BackupComplete در توضیحات سایت مایکروسافت هست؟ درسته؟
چون این هم مثل اون ، ورودی دریافت میکنه .


در ادامه ی جستجو درباره ی متد IVssBackupComponents.BeginBackupComplet ، به کلاس Task<TResult> برخوردم و در ادامه (هم که حالا شاید به این موضوع ربطی نداشته باشه) ، به کلاس Parallel .
کلاس Parallel را چند روز پیش ، در کدی که میخواستم برای جستجوی فایل ها استفاده کنم و در جریان پست های بالاترکه لینک داده بودم (برای سریعترین شیوه ی جستجوی فایل) :

Fastest way searching specific files

از متد Parallel.ForEach (که از دلیگیت Action<T> برای ورودی اش استفاده میکنه) برای اینکه بصورت موازی برنامه نویسی کنه ، استفاده کرد که منم توی کدم ازش استفاده کردم .
اگه اشتباه نکنم ، شما قبلا گفتین برنامه نویسی موازی ، بصورتی هست که از چند هسته بصورت همزمان بشه استفاده کرد. درسته دیگه؟ الان اون مطالب ، برابر استفاده از کلاس Parallel هست؟ یعنی وقتی از این کلاس و اعضاش (مثل همین متد Parallel.ForEach) استفاده میکنیم ، هر حلقه داخل یه نخ یا حتی داخل هر هسته اجرا میشه؟ بعد اینکه اما من کدم را تست کردم (و در پایین کد را میدم) ، برای من که بازم توی تسک منیجر یه هسته را بیشتر نتونست درگیر کنه و فرق خاصی با foreach معمولی نداشت (پردازنده ام i5 4460 هه و چهار هسته ای و بیشتر از 25 درصد برای اون پروسه را نتونست درگیر کنه) .
بعد این کلاس متد Parallel ، کاربرد ابتدایی از برنامه نویسی موازی و استفاده ی همزمان در چند هسته هست؟ آخه قبلا گفته بودین برنامه نویسی موازی ، سخت هه و یادگیریش خیلی طول میکشه.

این هم کد من (که در درایوها ، فایل ها و فولدرها را جستجو میکنه اما همونطور که گفتم ، در foreach معمولی و Parallel.ForEach ، فرق خاصی نداشتش) :


کد:
        private void Button9_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            this.FileFolderCounter = 0;
            this.SearchInDirectory(@"E:\");
            //this.label1.Text = this.FileFolderCounter.ToString();

            MessageBox.Show("complete");
        }

        int FileFolderCounter;

        private void SearchInDirectorySynchronize(string path)
        {
            try
            {

                DirectoryInfo folderInfo = new DirectoryInfo(path);
                DirectoryInfo[] innerFolderInfos = folderInfo.GetDirectories();

                if (innerFolderInfos.Length > 0)  // تا زمانی که فقط پوشه پیدا بشه
                {
                    Parallel.ForEach(innerFolderInfos, innerFolderInf => this.SearchInDirectory(innerFolderInf.FullName));
                  
                }

                FileInfo[] innerFileInfos = folderInfo.GetFiles();
                if (innerFileInfos.Length > 0)  // تا زمانی که فایل پیدا بشه
                {
                    List<FileInfo> listFileFolders = new List<FileInfo>(innerFileInfos);
                    listFileFolders.Add(new FileInfo(path));
                    this.FileFolderCounter += innerFileInfos.Length;
                    foreach (FileInfo fileFolderInf in listFileFolders)
                    {
                        //listBox1.Items.Add(fileFolderInf.FullName);
                    }
                }
                else
                {
                    //listBox1.Items.Add(path);
                }
                this.FileFolderCounter++;
            }
            catch (Exception)
            {

            }
        }

---------

بعد اینکه کلاس Task<T> ، موارد کاربردش کجاست؟ شبیه کلاس Parallel ، باعث میشه کدهاش بصورت موازی و در چند هسته بصورت همزمان اجرا بشه؟
چون در مقاله ای ، همچین چیزی نوشته بود :

https://programming.tosinso.com/tutorials/33026/%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-parallel-%D8%AF%D8%B1-%D8%B3%DB%8C-%D8%B4%D8%A7%D8%B1%D9%BE-%D8%A2%D8%B4%D9%86%D8%A7%DB%8C%DB%8C-%D8%A8%D8%A7-%DA%A9%D9%84%D8%A7%D8%B3-task-%D8%AF%D8%B1-%D8%B3%DB%8C-%D8%B4%D8%A7%D8%B1%D9%BE
 
آخرین ویرایش:

the_king

مدیرکل انجمن
خیلی ممنونم استاد علی بابت هر دو جواب :rose:
هر چند توی alphavss ، متد IVssBackupComponents.BackupComplete را داریم اما فکر نکنم این متد در اونجا برابر با همین نام از متد در توضیحات مایکروسافت باشه چون اون ورودی دریافت میکنه اما این نمیکنه . احتمالا متد IVssBackupComponents.BeginBackupComplete در alphavss برابر با متد IVssBackupComponents::BackupComplete در توضیحات سایت مایکروسافت هست؟ درسته؟
چون این هم مثل اون ، ورودی دریافت میکنه .

تفاوت بین زبان ها میتونه باعث تفاوت در پیاده سازی بشه، خیلی عادیه که پیاده سازی موردی در زبان دیگری متفاوت باشه، مخصوصا در Wrapper ها.
گاهی لازمه رخدادی ایجاد بشه و در خلال اون رخداد عملیات مفصلی هم انجام بشه، حتی در نخ مجزایی. در اینجور موارد تقسیم کردن متد رخداد به دو بخش Begin و End کمک می کنه که برنامه نویس با خیال آسوده فعالیتش رو با اعلام Begin آغاز کنه و عملیات رو انجام بده و با End خاتمه رو اعلام کنه. مثل نمونه های داخل NET.
به همین جهت نه Begin و نه End به تنهایی معادل متد اصلی نیستند.

در ادامه ی جستجو درباره ی متد IVssBackupComponents.BeginBackupComplet ، به کلاس Task<TResult> برخوردم و در ادامه (هم که حالا شاید به این موضوع ربطی نداشته باشه) ، به کلاس Parallel .
کلاس Parallel را چند روز پیش ، در کدی که میخواستم برای جستجوی فایل ها استفاده کنم و در جریان پست های بالاترکه لینک داده بودم (برای سریعترین شیوه ی جستجوی فایل) :

Fastest way searching specific files

از متد Parallel.ForEach (که از دلیگیت Action<T> برای ورودی اش استفاده میکنه) برای اینکه بصورت موازی برنامه نویسی کنه ، استفاده کرد که منم توی کدم ازش استفاده کردم .
اگه اشتباه نکنم ، شما قبلا گفتین برنامه نویسی موازی ، بصورتی هست که از چند هسته بصورت همزمان بشه استفاده کرد. درسته دیگه؟ الان اون مطالب ، برابر استفاده از کلاس Parallel هست؟ یعنی وقتی از این کلاس و اعضاش (مثل همین متد Parallel.ForEach) استفاده میکنیم ، هر حلقه داخل یه نخ یا حتی داخل هر هسته اجرا میشه؟ بعد اینکه اما من کدم را تست کردم (و در پایین کد را میدم) ، برای من که بازم توی تسک منیجر یه هسته را بیشتر نتونست درگیر کنه و فرق خاصی با foreach معمولی نداشت (پردازنده ام i5 4460 هه و چهار هسته ای و بیشتر از 25 درصد برای اون پروسه را نتونست درگیر کنه) .
بعد این کلاس متد Parallel ، کاربرد ابتدایی از برنامه نویسی موازی و استفاده ی همزمان در چند هسته هست؟ آخه قبلا گفته بودین برنامه نویسی موازی ، سخت هه و یادگیریش خیلی طول میکشه.

این هم کد من (که در درایوها ، فایل ها و فولدرها را جستجو میکنه اما همونطور که گفتم ، در foreach معمولی و Parallel.ForEach ، فرق خاصی نداشتش) :
کد:
        private void Button9_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            this.FileFolderCounter = 0;
            this.SearchInDirectory(@"E:\");
            //this.label1.Text = this.FileFolderCounter.ToString();

            MessageBox.Show("complete");
        }

        int FileFolderCounter;

        private void SearchInDirectorySynchronize(string path)
        {
            try
            {

                DirectoryInfo folderInfo = new DirectoryInfo(path);
                DirectoryInfo[] innerFolderInfos = folderInfo.GetDirectories();

                if (innerFolderInfos.Length > 0)  // تا زمانی که فقط پوشه پیدا بشه
                {
                    Parallel.ForEach(innerFolderInfos, innerFolderInf => this.SearchInDirectory(innerFolderInf.FullName));
                 
                }

                FileInfo[] innerFileInfos = folderInfo.GetFiles();
                if (innerFileInfos.Length > 0)  // تا زمانی که فایل پیدا بشه
                {
                    List<FileInfo> listFileFolders = new List<FileInfo>(innerFileInfos);
                    listFileFolders.Add(new FileInfo(path));
                    this.FileFolderCounter += innerFileInfos.Length;
                    foreach (FileInfo fileFolderInf in listFileFolders)
                    {
                        //listBox1.Items.Add(fileFolderInf.FullName);
                    }
                }
                else
                {
                    //listBox1.Items.Add(path);
                }
                this.FileFolderCounter++;
            }
            catch (Exception)
            {

            }
        }
همانطور که قبلا اشاره کرده بودم و خودتون هم امتحان کرده بودید، نخ های یک پروسه روی دو هسته اجرا نمیشه، روی یک هسته اجرا میشه. شما هر چند تا نخ هم که بصورت دستی یا با کمک Parallel.ForEach یا هر روش دیگری برای اجرای یک روتین بسازید، همچنان یک پروسه دارید با تعدادی نخ و این پروسه و داده هاش در هر لحظه صرفا روی یک هسته قابل دسترسی ئه و اجرای همزمانی روی چندین هسته نخواهد داشت. اجرای چند نخی معادل چند هسته ای نیست.
و همانطور هم قبلا چندین بار یادآوری کردم هر الگوریتمی بصورت موازی قابل اجرا نیست و همه الگوریتم ها نمی توانند از اجرای موازی برای بهبود کارایی استفاده کنند. همانطور که وقتی شما هارد دیسک تان را درگیرعملیاتی مثل کپی فایل ها کرده اید، اجرا همزمان عملیات دیگری روی اون هارد دیسک نه تنها باعث صرفه جویی در زمان پایان دو عملیات نمیشه، بلکه در مجموع کند تر از اجرای عملیات دوم بعد از اولی هم میشه.

بعد اینکه کلاس Task<T> ، موارد کاربردش کجاست؟ شبیه کلاس Parallel ، باعث میشه کدهاش بصورت موازی و در چند هسته بصورت همزمان اجرا بشه؟
چون در مقاله ای ، همچین چیزی نوشته بود :

https://programming.tosinso.com/tutorials/33026/%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-parallel-%D8%AF%D8%B1-%D8%B3%DB%8C-%D8%B4%D8%A7%D8%B1%D9%BE-%D8%A2%D8%B4%D9%86%D8%A7%DB%8C%DB%8C-%D8%A8%D8%A7-%DA%A9%D9%84%D8%A7%D8%B3-task-%D8%AF%D8%B1-%D8%B3%DB%8C-%D8%B4%D8%A7%D8%B1%D9%BE
اصلا همچین چیزی ننوشته بود. شما چه در مورد Parallel و چه در مورد اون مقاله، اشاره ای به هسته یا core می بینید؟ کجای منابع تون صحبت از چند هسته ای شده؟
وقتی یکسری عملیات مستقل دارید که نه شروع و نه پایان و نه نتیجه هر کدوم شون تاثیری روی سایرین نداره، می توانید بصورت Task تعریف شون کنید تا بصورت خودکار و بهینه با توجه به منابع سیستم در تعداد نخ مناسب اجرا بشن.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
تفاوت بین زبان ها میتونه باعث تفاوت در پیاده سازی بشه، خیلی عادیه که پیاده سازی موردی در زبان دیگری متفاوت باشه، مخصوصا در Wrapper ها.
گاهی لازمه رخدادی ایجاد بشه و در خلال اون رخداد عملیات مفصلی هم انجام بشه، حتی در نخ مجزایی. در اینجور موارد تقسیم کردن متد رخداد به دو بخش Begin و End کمک می کنه که برنامه نویس با خیال آسوده فعالیتش رو با اعلام Begin آغاز کنه و عملیات رو انجام بده و با End خاتمه رو اعلام کنه. مثل نمونه های داخل NET.
به همین جهت نه Begin و نه End به تنهایی معادل متد اصلی نیستند.

سلامی مجدد
خیلی ممنون استاد علی
پس میشه حدودا روی هر دو (متد Begin و End) یا مخصوصا متد End اش حساب باز کرد دیگه؟
مثل رویداد ResizeBegin و ResizeEnd برای کنترل فرم . درسته؟

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

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


اصلا همچین چیزی ننوشته بود. شما چه در مورد Parallel و چه در مورد اون مقاله، اشاره ای به هسته یا core می بینید؟ کجای منابع تون صحبت از چند هسته ای شده؟
وقتی یکسری عملیات مستقل دارید که نه شروع و نه پایان و نه نتیجه هر کدوم شون تاثیری روی سایرین نداره، می توانید بصورت Task تعریف شون کنید تا بصورت خودکار و بهینه با توجه به منابع سیستم در تعداد نخ مناسب اجرا بشن.

در این مقاله ی زیر نوشته بودن :
"یکی از قابلیت های TPL این است که کارهای محوله را به صورت خودکار بین CPU های سیستم (در صورت وجود) توزیع می کند که این کار در پشت زمینه بوسیله CLR Thread Pool انجام می شود."
فکر کردم منظور از cpu همون هسته ها منظورشونه.


برنامه نویسی Parallel در سی شارپ :: مقدمه ای بر Task Parallel Library و کلاس Parallel در دات نت
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
تفاوت بین زبان ها میتونه باعث تفاوت در پیاده سازی بشه، خیلی عادیه که پیاده سازی موردی در زبان دیگری متفاوت باشه، مخصوصا در Wrapper ها.
گاهی لازمه رخدادی ایجاد بشه و در خلال اون رخداد عملیات مفصلی هم انجام بشه، حتی در نخ مجزایی. در اینجور موارد تقسیم کردن متد رخداد به دو بخش Begin و End کمک می کنه که برنامه نویس با خیال آسوده فعالیتش رو با اعلام Begin آغاز کنه و عملیات رو انجام بده و با End خاتمه رو اعلام کنه. مثل نمونه های داخل NET.
به همین جهت نه Begin و نه End به تنهایی معادل متد اصلی نیستند.

خیلی ممنون استاد علی
توی vss ، تابع BackupComplete که اصلا ورودی و خروجی ای نداره (نمیدونم با این حال به درد کجا میخوره) . تابع BeginBackupComplete را اگه سر آخر (بعد از متد DoSnapshotSet) فراخونی کنیم ، انگار اگه برای عملیات بکاپ مشکلی پیش نیاد و توابع های فراخونی شده ، Exception ای را ندن ، تابع BeginBackupComplete درست فراخونی میشه وگرنه اگه اون متدهای مربوط به عملیات بکاپ ، Exception را پرتاب کنن ، متد BeginBackupComplete هم موقع فراخونی ، خطای VssBadStateException رو میده . پس آیا از این حالت خطا دادن یا ندادن متد BeginBackupComplete میشه متوجه شد که بکاپ ، موفقیت آمیز بود یا نه؟
اون سئوال قبلی یعنی سئوال "پس کلاس Parallel و کلاس Task ها چیزی نیستن جز اینکه نخ ها و thread های جدید ایجاد میکنن؟" جوابش چیه؟ درسته؟

و اینکه درباره ی async و aware ، یه کم توضیح میدین؟
مقاله ها را هم خوندم ولی متوجه نشدم . در واقع متوجه نشدم که این دو کلمه دقیقا چی کار میکنن و کجاها میشه بکارشون برد و کجاها نمیشه .
مقاله ها هم اینا بودن (اون سایت مایکروسافت را تا نصف خوندم. تا سر Start tasks concurrently اما همین چیزها را متوجه نشدم) :

آشنایی با کلمات کلیدی async و await در زبان سی شارپ

و

Asynchronous programming in C#
 

جدیدترین ارسال ها

بالا