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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
چرا FormBorderStyle را روی None میذارم ، دیگه نمیشه فرم را جابجا کرد؟
یا به نوعی دیگه ، چجوری میشه یک فرم هم Border نداشته باشه و هم جابجا بشه؟
 

the_king

مدیرکل انجمن
میتونه بخاطر همون قضیه ای که توی Form و UserControl ، کلاس دیگه ای تعریف کردم ، باشه ؟
اگه DialogResult ای در کار نباشه نه، دلیلی نداره دکمه ای که کدی نداره فرمی رو ببنده، بالاخره یا OnClick و متد های مشابه کاری انجام میدن، یا رخداد Click و موارد مشابه رو جایی مدیریت کردید یا جاهایی خودتون فرم رو می بندید که فراموش کردید یا DialogResult ای در کار ئه. بالاخره یه جایی این اتفاق می افته. کد تون رو در حال اجرا Trace کنید محل اش پیدا میشه.

چرا FormBorderStyle را روی None میذارم ، دیگه نمیشه فرم را جابجا کرد؟
یا به نوعی دیگه ، چجوری میشه یک فرم هم Border نداشته باشه و هم جابجا بشه؟
با چی جابجا بشه؟ اون بخشی که باهاش میشد جابجا بشه رو حذف می کنید و فقط بخش Client می مونه که اصولا قرار نیست تو این مورد دخالتی داشته باشه.
فرم هایی که Title و Border ندارند اصولا یا برای نمایش Caption و Tooltip و Splash هستند که جابجا نمیشوند و یا فرم هایی که Skin و شکل اختصاصی دارند و کد نویس خودش برای جابجایی اش اونم از بخش دلخواه فرم اش کد می نویسه. خیلی غیر معموله که فرم از هر جاش قابل جابجایی باشه.
دو تا کار می توانید بکنید، یا می توانید موقع فشار کلید به پنجره رخداد فشار دکمه ماوس در بخش Non Client رو بفرستید که خیال کنه Caption داره که روش داره کلیک میشه و جابجاش کنه یا می توانید خودتون برای رخداد های ماوس کد بنویسید و فرم رو جابجا کنید. گزینه اول اصولی تر ئه، مگر اینکه بخواهید مثل WinAmp که پنجره هاش بهم نزدیک میشدند مثل آهن ربا میچسبیدند کار های خاصی انجام بدید.

کد:
    public partial class Form1 : Form
    {
        private const int WM_NCLBUTTONDOWN = 0xA1;
        private const int HT_CAPTION = 0x2;

        [DllImport("user32.dll")]
        private static extern bool ReleaseCapture();

        [DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            }
        }

        public Form1()
        {
            InitializeComponent();
        }
    }
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام استاد علی
ممنون
نمیدونم ینو قبلا پرسیدم یا نه (ولی جستجو کردم ، پیدا نکردم)
ولی من توابع Control.SuspendLayout و Control.ResumeLayout رو دقیق متوجه نشدم چی هستن و مخصوصا اینکه کاربردشون کجاست؟ (داخل designer این توابع فراخونی شدن)
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
استاد علی ، گفته بودین که یه برنامه بصورت پیش فرض فقط از یه هسته میتونه استفاده کنه . واسه منم همینطور بود (برنامه ی ساخته شده در ویژال استودیو رو مثلا توی یه حلقه تست کردم و پردازنده ام 4 هسته ای بود ، فقط 25 درصدش رو تونست استفاده کنه و بیشتر از اون رو نتونست) بجز اینکه بصورت موازی سازی نوشته شده باشن . خوب حالا اگه بصورت موازی سازی نوشته بشه ، این طوری هست که یا از 2 یا از 3 یا ز 4 و ... هسته میتونه همزمان استفاده کنه دیگه؟ یعنی مثلا در پردازنده ی 4 هسته ای اگه از 2 هسته استفده کنه ، پس 50 درصد را باید مشغول کنه ولی خیلی از برنامه ها مثلا ویژال استودیو ، در پردازنده ام ، در یک زمان (مثلا لود پروژه) ، حدودا 40 درصد را استفاده میکنه
دلیل این استفاده چیه؟ اگه از 2 هسته ی کامل بخواد استفاده کنه ، 50 درصد را باید استفاده کنه . پس چرا 40 درصد را استفاده میکنه؟
 

the_king

مدیرکل انجمن
استاد علی ، گفته بودین که یه برنامه بصورت پیش فرض فقط از یه هسته میتونه استفاده کنه . واسه منم همینطور بود (برنامه ی ساخته شده در ویژال استودیو رو مثلا توی یه حلقه تست کردم و پردازنده ام 4 هسته ای بود ، فقط 25 درصدش رو تونست استفاده کنه و بیشتر از اون رو نتونست) بجز اینکه بصورت موازی سازی نوشته شده باشن . خوب حالا اگه بصورت موازی سازی نوشته بشه ، این طوری هست که یا از 2 یا از 3 یا ز 4 و ... هسته میتونه همزمان استفاده کنه دیگه؟ یعنی مثلا در پردازنده ی 4 هسته ای اگه از 2 هسته استفده کنه ، پس 50 درصد را باید مشغول کنه ولی خیلی از برنامه ها مثلا ویژال استودیو ، در پردازنده ام ، در یک زمان (مثلا لود پروژه) ، حدودا 40 درصد را استفاده میکنه
دلیل این استفاده چیه؟ اگه از 2 هسته ی کامل بخواد استفاده کنه ، 50 درصد را باید استفاده کنه . پس چرا 40 درصد را استفاده میکنه؟
این 25 درصد که میگید معیار دقیقی از توان مصرفی پروسه شما در هسته نیست، یک معیار کلی، تخمینی و ظاهریه. صحبت وضعیت یک کسری از ثانیه است، نه کل زمان. همونطور که شما یکسره روبرو تون رو نمی بینید و پلک می زنید، سیستم عامل هم مدام منبعش رو از پروسه شما پس می گیره و دوبار تخصیص میده.

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

the_king

مدیرکل انجمن
سلام استاد علی
ممنون
نمیدونم ینو قبلا پرسیدم یا نه (ولی جستجو کردم ، پیدا نکردم)
ولی من توابع Control.SuspendLayout و Control.ResumeLayout رو دقیق متوجه نشدم چی هستن و مخصوصا اینکه کاربردشون کجاست؟ (داخل designer این توابع فراخونی شدن)
از این موارد زیاد ئه، یک جاهایی بجای Resume و Suspend از Begin و End و ... هم استفاده میشه. روال کلی اینه، کارهایی هست که باید در واکنش به یکسری تغییرات حتما انجام بشه، فرضا اگه آیتمی به لیست اضافه می شه یا محتوای آیتم تغییری می کنه، باید لیست از نو رسم بشه. یا اگه اندازه کنترل ای تغییر کنه، محتویات داخلش بر اساس تغییرات ابعاد از نو جابجا بشن و ... زمانی که تغییرات فقط یکی دو تا مورد ئه، اشکالی نداره که برای هر کدوم یکبار از نو کار ها انجام بشه، ولی در اغلب موارد تغییراتی که میدید، یکی دو تا نیست و زیاده. فرضا صد تا آیتم داره یکی یکی به لیست اضافه میشه یا یک کنترل چندین تغییر مشخصه پی در پی پیدا می کنه. اگه قرار باشه برای هر کدوم یکبار اون کارها که باید انجام میشد، تکرار بشه، فرضا از نو رسم صورت بگیره، ممکنه خیلی سر بار ایجاد کنه، روال بیخودی کند بشه یا موقع نمایش کنترل پر پر بزنه. برای اینجور موارد سعی می کنند یک همچین متد هایی رو طراحی کنند، که اعلام کنید میخواهم یکسری تغییرات رو یکجا بدم، از فلان جای کد تا زمانی که اعلام می کنید تلاشی در واکنش به تغییرات انجام نشه، یعنی فرضا روال رسم مجدد غیر فعال بشه. زمانی که تغییرات تون تموم شد با متد دوم اعلام می کنید که کار من تمام شد و حالا فقط یکبار اون روال که لازمه انجام میشه. استفاده از اینها برای افزایش کارایی ئه. که هی برای یک تغییر کوچیک یک روال تکراری انجام نشه چون تغییرات بعدی در راه اند و فعلا نیازی به نمایش تغییرات نیست.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
این 25 درصد که میگید معیار دقیقی از توان مصرفی پروسه شما در هسته نیست، یک معیار کلی، تخمینی و ظاهریه. صحبت وضعیت یک کسری از ثانیه است، نه کل زمان. همونطور که شما یکسره روبرو تون رو نمی بینید و پلک می زنید، سیستم عامل هم مدام منبعش رو از پروسه شما پس می گیره و دوبار تخصیص میده.
ممنون استاد علی
نه مسئله ام این نیست . این قضیه برام جا افتاد و قبلا هم گفته بودین . میدونم وقتی یه پروسه (نخ از یک پروسه) داره در یک هسته اجرا میشه ، هر وقت سیستم عامل دلش خواست ، میتونه اون نخ رو متوقف کنه (نه صرفا اینکه حتما برنامه نویس اون نخ رو متوقف کرده باشه) و یه نخ دیگه (حتی از پروسه و برنامه ی دیگه) رو اجرا کنه و هر وقت لازم به ادامه ی نخ پروسه ی قبلی بود ، اون نخ رو ادامه بده که این ادامه دادن هم ممکنه در همون هسته انجام نگیره (ممکنه اون هسته ی قبلی ، توسط یه نخ دیگه اشغال شده باشه و هر دلیل دیگه ای) و همه ی اینا ممکنه در کمتر از یک میلی ثانیه اتفاق بیافته


موازی سازی رو معادل چند هسته ای قرار ندین. ممکنه روی یک هسته موازی سازی صورت بگیره، موازی سازی اجرای همزمان ئه، از نظر سخت افزاری ممکنه در یک هسته هم اینکار اتفاق بیافته، شما که وقتی در مورد موازی سازی حرف می زنید در مورد توانایی یک پردازنده خاص صحبت نمی کنید. به این معنی هم نیست که حتما 100 درصد توان هسته صرف یک پروسه بشه.
منظورم از اینکه پروژه ام 25 درصد رو توی پردازنده ی 4 هسته ای استفاده میکنه ، اصلا این نبود که یک هسته رو کاملا قبضه کنه . توضیحات رو در بالا دادم و میدونم ممکنه هر لحظه ، در یک نخ و یا حتی یک هسته اجرا بشه
موازی سازی ، ممکنه روی یک هسته انجام بگیره؟!! یعنی میتونه 2 هسته ی همزمان رو درگیر نکنه؟ اگه آره ، پس همین روال عادی هم همین کار رو انجام میده . چه نیازی به موازی سازی کردن هست؟!
کلا منظورم اینه که توی موازی سازی ، توی پردازنده ی 4 هسته ای ، اگه از 2 هسته هم ویژال استودیو استفاده کنه (چون در پروسه ی ویژال استودیو ، از 40 درصد ، یعنی بالای 25 درصد یعنی بالای یک هسته رو استفاده میکنه . البته این به معنای قبضه کردن اون نخ و اون هسته نیست همونطور که پروسه ی پروژه من که 25 درصد یعنی از تقریبا مام توان یک هسته استفاده میکنه ، به معنای قبضه کردن یک هسته نیست که در بالا توضیح دادم) چرا حالا از تمام وان اون دو هسته استفاده نمیکنه؟ یعنی چرا نمیتونه حداقل بالای 48 درصد رو استفاده کنه؟


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

the_king

مدیرکل انجمن
ممنون استاد علی
نه مسئله ام این نیست . این قضیه برام جا افتاد و قبلا هم گفته بودین . میدونم وقتی یه پروسه (نخ از یک پروسه) داره در یک هسته اجرا میشه ، هر وقت سیستم عامل دلش خواست ، میتونه اون نخ رو متوقف کنه (نه صرفا اینکه حتما برنامه نویس اون نخ رو متوقف کرده باشه) و یه نخ دیگه (حتی از پروسه و برنامه ی دیگه) رو اجرا کنه و هر وقت لازم به ادامه ی نخ پروسه ی قبلی بود ، اون نخ رو ادامه بده که این ادامه دادن هم ممکنه در همون هسته انجام نگیره (ممکنه اون هسته ی قبلی ، توسط یه نخ دیگه اشغال شده باشه و هر دلیل دیگه ای) و همه ی اینا ممکنه در کمتر از یک میلی ثانیه اتفاق بیافته
منظورم از اینکه پروژه ام 25 درصد رو توی پردازنده ی 4 هسته ای استفاده میکنه ، اصلا این نبود که یک هسته رو کاملا قبضه کنه . توضیحات رو در بالا دادم و میدونم ممکنه هر لحظه ، در یک نخ و یا حتی یک هسته اجرا بشه
موازی سازی ، ممکنه روی یک هسته انجام بگیره؟!! یعنی میتونه 2 هسته ی همزمان رو درگیر نکنه؟ اگه آره ، پس همین روال عادی هم همین کار رو انجام میده . چه نیازی به موازی سازی کردن هست؟!
موازی سازی میتونه روی یک هسته انجام بشه، اما لازمه اش اینه که اولا کد هایی که همزمان اجرا میشن مناسب اینکار باشه و ثانیا هسته توانایی اینکار رو داشته باشه و ثالثا کد برای اجرای موازی نوشته شده باشه. مثل اینه که از کاربر بپرسیم آیا مطمئنی میخوای این فایل رو حذف کنی و بعد اگه پاسخ Yes بود فایل رو حذف کنیم. این کد باید ترتیبی اجرا بشه، برای موازی سازی مناسب نیست. این کد رو موازی اجراش کنیم چی میشه؟ فایل رو حذف کنیم و همزمان از کاربر بپرسیم آیا رضایت داشتی که فایل رو حذف کردیم یا دلخور شدی؟ نمیشه که. هسته برای افزایش کارایی فرمان هایی رو موازی اجرا می کنه که مستقل از هم هستند و نتیجه شون روی هم تاثیری نداره. در ضمن توانایی سخت افزاری پردازنده هم ملاک ئه، فرضا فقط یک فرمان مرتبط با حافظه رو همزمان با یک فرمان مربوط به محاسبات اعشاری انجام میده، چون بخش های سخت افزاری شون مستقل ئه. نه اینکه دو فرمان مرتبط با حافظه یا دو فرمان مرتبط با محاسبات اعشاری رو همزمان اجرا کنه. هدفش هم اینه که بخش مرتبط با حافظه یا محاسبات اعشاری اش بیکار نمونه. ممکنه در یک لحظه همچین شرایطی برای اجرای موازی باشه و یک زمانی نباشه. در هر صورت اینها کاملا مرتبط با معماری و خصوصیات یک پردازنده خاص هستند، نمیشه برای همه پردازنده ها یک حکم قطعی داد. و در نظر بگیرید که خیلی تفاوته بین اجرای موازی کد های دو نخ از یک پروسه و اجرای موازی کد های دو پروسه متفاوت. سوئیچ بین دو پروسه سربار داره، پس خیلی مطلوب نیست، اما این سربار از بیکار بودن یک بخش از هسته بهتره.

کلا منظورم اینه که توی موازی سازی ، توی پردازنده ی 4 هسته ای ، اگه از 2 هسته هم ویژال استودیو استفاده کنه (چون در پروسه ی ویژال استودیو ، از 40 درصد ، یعنی بالای 25 درصد یعنی بالای یک هسته رو استفاده میکنه . البته این به معنای قبضه کردن اون نخ و اون هسته نیست همونطور که پروسه ی پروژه من که 25 درصد یعنی از تقریبا مام توان یک هسته استفاده میکنه ، به معنای قبضه کردن یک هسته نیست که در بالا توضیح دادم) چرا حالا از تمام وان اون دو هسته استفاده نمیکنه؟ یعنی چرا نمیتونه حداقل بالای 48 درصد رو استفاده کنه؟
چطور اینکار رو بکنه؟ فکر می کنید ویژوال استدیو فقط یک کاری رو انجام میده که کاملا مستقل ئه و نه نیازی به ورودی داره و نه خروجی و بی وقفه میتونه به کارش ادامه بده و معطل موردی نشه؟
یعنی ویژوال استدیو کدی رو اجرا کنه که نه نیازی به خروجی هیچ پروسه دیگه ای داشته باشه و نه روال اش نیازمند دریافت اطلاعات از هارد دیسک باشه و...
معمولا هر کدی یکجا احتیاج به ورودی داره یا به جایی خروجی میده و تا روال مرتبط تموم نشه کار دیگه ای برای انجام نداره. شما سریعترین روال Render گیری دنیا رو می نویسید، خوب، خروجی شو کجا بنویسه؟ هارد دیسک که برای نوشتن کند ئه و بالاخره معطل اش می کنه، موقتا در RَAM هم نویسه نهایتا RAM پر میشه و باید معطل بشه تا محتویات RAM روی هارد دیسک بیاد. برای Encode کردن خروجی فشرده نشده هم که وقت لازمه. پس در هر صورت نمیشه که کل توان صرف کاری بشه که معطل مورد دیگه ای خواهد شد. این خیلی طبیعیه که پروسه مواقعی کاری برای انجام نداره. ویژوال استدیو با وجود تلاش اش بالاخره وقت هایی منتظر و بیکار ئه، منتظر ئه که کاری که به جایی درخواست داده تموم بشه. تا تموم نشه کار دیگه ای نمیتونه انجام بده.
 

SajjadKhati

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

SajjadKhati

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


کد:
Image img = ((DataObject)e.Data).GetImage();
            MessageBox.Show(img.ToString());

ولی یه فایل عکس را توش درگ و دروپ کردم ، ارور میده . البته میدونم بجای این کار ، باید مسیر فایل را بگیرم و از مسیر فایل ، شی ای از Bitmap و ... بسازم ولی حالا میخواستم بدونم توسط کد بالا ، اگه فایل دراپ و رها شده ، فایل عکس باشه ، این کار چرا امکان نداره؟ یا بهتر اینکه بپرسم اصلا متد GetImage و GetAudioStream در کلاس DataObject ، برای چی هه؟
و اینکه اطلاعات فایل هایِ میانبرِ (شورتکات) درگ و دروپ شده را چجوری میشه گرفت؟
کلا درگ و دراپ چد نوع اند؟ یکی درگ و دراپِ فایل و یکی درگ و دراپِ متن و یکی درگ و دراپِ شورتکات هاست؟
روال کلی درگ و دراپِ کنترل ها چجوری هه؟ مثلا چجوری با انتخاب کنترلی ، اون کنترل در همون نرم افزار ، عمل درگ و دراپ انجام میشه روش ؟ (جابجایی نه)

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

the_king

مدیرکل انجمن
ممنون استاد علی . درباره ی توضیح توابع Resume و ... هم ممنون
------------------------------------------------------
در رویداد درگ و دروپ فرم ، کد زیر را نوشتم :


کد:
Image img = ((DataObject)e.Data).GetImage();
            MessageBox.Show(img.ToString());

ولی یه فایل عکس را توش درگ و دروپ کردم ، ارور میده . البته میدونم بجای این کار ، باید مسیر فایل را بگیرم و از مسیر فایل ، شی ای از Bitmap و ... بسازم ولی حالا میخواستم بدونم توسط کد بالا ، اگه فایل دراپ و رها شده ، فایل عکس باشه ، این کار چرا امکان نداره؟ یا بهتر اینکه بپرسم اصلا متد GetImage و GetAudioStream در کلاس DataObject ، برای چی هه؟

ربطی به محتویات فایل نداره که بگید اگه فایل عکس بود امکان داشته باشه، منبعی که داده Drag رو ایجاد می کنه مهمه. وقتی فایلی رو Exporer دارید Drag می کنید فایل رو که باز نمی کنه که محتویات تصویری شو در Data قرار بده. برای Explorer که اهمیتی نداره محتویات فایل یا پوشه چیه، مشخصات مسیرش رو Drag می کنه. این روال Explorer ئه، نه برنامه X یا Y. نمیتونید هم از قبل پیش بینی کنید که منبع Drag کجا است و از چه نوعیه. ممکنه فایلی در حد گیگابایت باشه یا فرمتش قابل فهم نباشه، برای Explorer لزومی نداره محتویاتش رو برای Drag کردن بخونه.
اما ممکنه یک منبع Drag بخواد Image رو انتقال بده، اون موقع GetImage بدرد میخوره. و البته انواع داده هایی که در Data میتونه قرار بگیره محدود نیست، مثل Clipboard. اینکه مواردی مثل GetImage رو اضافه کردن بخاطر استفاده بیشتر و ساده کردن کد ئه، نه اینکه فقط همین ها است.

و اینکه اطلاعات فایل هایِ میانبرِ (شورتکات) درگ و دروپ شده را چجوری میشه گرفت؟

یک کمپوننت COM ای هست به نام Microsoft Shell Control And Automation که به Reference پروژه تون اضافه اش می کنید، اطلاعاتی که مربوط به Shell ویندوز میشه، هر موردی که در Explorer هم استفاده شده، اعم از مشخصات Shortcut و Property های اضافی فایل رو میتوانید ازش بگیرید.
Scriptable Shell Objects
توی گوگل هم جستجوش کنید مثال های زیادی ازش هست.


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

روال کلی درگ و دراپِ کنترل ها چجوری هه؟ مثلا چجوری با انتخاب کنترلی ، اون کنترل در همون نرم افزار ، عمل درگ و دراپ انجام میشه روش ؟ (جابجایی نه)
یک کنترلی منبع Drag ئه، فعلا نه میدونه مقصد کجاست و نه میدونه قبول می کنه یا نه. فقط داده ای با فرمت دلخواهش رو همراه Drag ایجاد می کنه، متد DoDragDrop برای اینکار ئه. مقصد هم یک کنترل دیگه است که دکمه ماوس رو روش رها می کنید، میتونه Drop رو قبول بکنه و یا نکنه. منطق ثابت و مشخصی هم نداره، چون خودتون دارید Drag می کنید داده و نوعش رو هم خودتون مشخص می کنید، به هر طریقی که دوست دارید. سایر برنامه ها هم ممکنه اصلا قابلیت استقاده داده اش رو نداشته باشند یا بطرز نامناسبی تفسیر اش کنند. در مورد Clipboard هم همینطوره.

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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
ممنون استاد علی
میشه توی رویدادهای کیبرد ، کلید tab و esc و یا کلیدهای ترکیبی ctrl+alt+del را کپچر کرد؟ اگه آره ، چجوری؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام مجدد
من کد زیر رو پیدا کردم برای قضیه ی tab :


کد:
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData == Keys.Tab)
                return false;
            return base.ProcessDialogKey(keyData);
        }

الان این تابع ProcessDialogKey ، فقط وقتی که کلیدهای نامرئی مثل tab و enter را بزنیم اجرا میشه و در صورتی که این تابع اجرا نشه (override کنیم و return false رو برگردونیم) ، این کلیدها را میبینه؟
بعد اینکه توابعی که اسم شون با On شروع میشن هم همینطوره؟ یعنی هر رویدادی (مثلا رویداد Click در Form1) میخواد اجرا بشه ، اول متد OnClick اجرا میشه و در صورت اجرای متد OnClick در کلاس Control ، باعث اجرای اون شی ی ز دلیگیت ای که به ون رویداد نسبت دادیم (تابعی که به رویداد مورد نظر وصل کردیم) میشه وگرنه اجرا نمیشه؟ ولی فکر نکنم این دومی که گفتم صحیح باشه . اگه نیست ، پس توابع Virtual ای که با On شروع میشن ، چی هستن و کجا کاربرد دارن؟
 
آخرین ویرایش:

the_king

مدیرکل انجمن
سلام
ممنون استاد علی
میشه توی رویدادهای کیبرد ، کلید tab و esc و یا کلیدهای ترکیبی ctrl+alt+del را کپچر کرد؟ اگه آره ، چجوری؟
Ctrl Alt Del رو نه. در سیستم عامل های قدیمی میشد ولی چون یک ترکیب کلیدی سیستمی ئه دیگه به برنامه ها اطلاع داده نمیشه.
SetWindowsHookEx

سلام مجدد
من کد زیر رو پیدا کردم برای قضیه ی tab :


کد:
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData == Keys.Tab)
                return false;
            return base.ProcessDialogKey(keyData);
        }
الان این تابع ProcessDialogKey ، فقط وقتی که کلیدهای نامرئی مثل tab و enter را بزنیم اجرا میشه و در صورتی که این تابع اجرا نشه (override کنیم و return false رو برگردونیم) ، این کلیدها را میبینه؟

مساله اینه که کی ببینه. اگر منظورتون خود کنترل ئه، دیده که این متد فراخوانی شده، خود ProcessDialogKey به دیدن کاری نداره.
بحث دیدن نیست. کلید با یکسری سلسله مراتب بررسی میشه. اینکه true برگردونه معنی اش اینه که این کلید اینجا پردازش شد و کارش به پایان رسید، سلسله مراتب بررسی در اینجا تموم شد.
کنترل خودش با IsInputKey مشخص می کنه که برایش فلان کلید تعریف شده و وظیفه ای داره یا کاری باهاش نداره. اگه بگه Tab برای من تعریف شده، دیگه به اینجا نمیرسه و جزو DialogKey ها نخواهد بود. چطور که کلید های بالا و پایین برای بعضی کنترل ها کاربرد دارند. هر کنترلی برای یکسری کلید ها کاری برای انجام داره، برای سایر کلید ها نداره. فرضا ممکنه یک TextBox بخواد با Enter سطر جدید ایجاد کنه، قرار نیست برای همه کنترل ها Enter یک DialogKey محسوب بشه. یک کنترلی با Tab ممکنه مقدار عوض کنه. این چیزی نیست که از قبل برای فرم مشخص باشه. برای همین زمانی که کلیدی توسط کنترل به عنوان کلید عادی پردازش نشد در این متد ProcessDialogKey بررسی میشه که کاری رویش انجام میشه یا نه.
بعد اینکه توابعی که اسم شون با On شروع میشن هم همینطوره؟ یعنی هر رویدادی (مثلا رویداد Click در Form1) میخواد اجرا بشه ، اول متد OnClick اجرا میشه و در صورت اجرای متد OnClick در کلاس Control ، باعث اجرای اون شی ی ز دلیگیت ای که به ون رویداد نسبت دادیم (تابعی که به رویداد مورد نظر وصل کردیم) میشه وگرنه اجرا نمیشه؟ ولی فکر نکنم این دومی که گفتم صحیح باشه . اگه نیست ، پس توابع Virtual ای که با On شروع میشن ، چی هستن و کجا کاربرد دارن؟
رویداد Click یک رخداد خارجیه، باید جایی فراخوانی بشه تا اتفاق بیافته، باید Invoke بشه. و Invoke شدنش هم توسط OnClick یا هر متد دیگه ای که اینکار رو بکنه انجام میشه، نه خود به خودی.
حالا وقتی شما OnClick رو از کار بندازید، Invoke شدن Click رو حذف کردید، رخداد Click خود به خود که رخ نمیده. پس Click رو هم به هر متدی متصل کنید بی فایده است و دیگه رخ نخواهد داد چون Invoke اش جایی اتفاق نمی افته.
Control یک کلاس عمومی ئه، قرار نیست Click همه Control ها عین هم باشه. ممکنه شما لازم باشه روی موقعیت خاصی از کنترلی کلیک کنید تا Click حساب بشه، شاید لازمه شرایط خاصی باشه تا Click رخ بده. پس لازمه که OnClick ای باشه که بتوانید مراحل رخ دادن رخداد Click رو تغییر بدید. اگه OnClick ای در کار نبود یا Virtual نبود، تغییر دادن روال Click برای Control های سفارشی سخت میشد. همه On ها همینطور هستند.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سئوال بعدی اینکه چرا در کد زیر که اعضای آرایه را در حلقه ی for جداگانه null میکنم ، بعد از GC.Collect ، چیزی از حافظه ی اشغالی ، پاک نمیشه :

کد:
int b = 300000;
            Button[] a = new Button[b];

            for (int i = 0; i < a.Length; i++)
            {
                a[i] = new Button();
            }

            for (int i = 0; i < a.Length; i++)
            {
                a[i] = null;
            }

            a = null;
            GC.Collect();
سلام. ممنون
استاد علی ، اینو از یه جای دیگه هم پرسیدم (از استاد آرمین) ، گفتش بعد از اولین فراخونی GC.Collect() ، متد GC.WaitForPendingFinalizers() رو باید صدا بزنم و بعد دوباره متد GC.Collect() رو . یعنی کد درستش اینه :


کد:
            int b = 300000;
            Button[] a = new Button[b];


            for (int i = 0; i < a.Length; i++)
            {
                a[i] = new Button();
            }
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = null;
            }


            a = null;
         
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
Ctrl Alt Del رو نه. در سیستم عامل های قدیمی میشد ولی چون یک ترکیب کلیدی سیستمی ئه دیگه به برنامه ها اطلاع داده نمیشه.
SetWindowsHookEx


مساله اینه که کی ببینه. اگر منظورتون خود کنترل ئه، دیده که این متد فراخوانی شده، خود ProcessDialogKey به دیدن کاری نداره.
بحث دیدن نیست. کلید با یکسری سلسله مراتب بررسی میشه. اینکه true برگردونه معنی اش اینه که این کلید اینجا پردازش شد و کارش به پایان رسید، سلسله مراتب بررسی در اینجا تموم شد.
کنترل خودش با IsInputKey مشخص می کنه که برایش فلان کلید تعریف شده و وظیفه ای داره یا کاری باهاش نداره. اگه بگه Tab برای من تعریف شده، دیگه به اینجا نمیرسه و جزو DialogKey ها نخواهد بود. چطور که کلید های بالا و پایین برای بعضی کنترل ها کاربرد دارند. هر کنترلی برای یکسری کلید ها کاری برای انجام داره، برای سایر کلید ها نداره. فرضا ممکنه یک TextBox بخواد با Enter سطر جدید ایجاد کنه، قرار نیست برای همه کنترل ها Enter یک DialogKey محسوب بشه. یک کنترلی با Tab ممکنه مقدار عوض کنه. این چیزی نیست که از قبل برای فرم مشخص باشه. برای همین زمانی که کلیدی توسط کنترل به عنوان کلید عادی پردازش نشد در این متد ProcessDialogKey بررسی میشه که کاری رویش انجام میشه یا نه.

رویداد Click یک رخداد خارجیه، باید جایی فراخوانی بشه تا اتفاق بیافته، باید Invoke بشه. و Invoke شدنش هم توسط OnClick یا هر متد دیگه ای که اینکار رو بکنه انجام میشه، نه خود به خودی.
حالا وقتی شما OnClick رو از کار بندازید، Invoke شدن Click رو حذف کردید، رخداد Click خود به خود که رخ نمیده. پس Click رو هم به هر متدی متصل کنید بی فایده است و دیگه رخ نخواهد داد چون Invoke اش جایی اتفاق نمی افته.
Control یک کلاس عمومی ئه، قرار نیست Click همه Control ها عین هم باشه. ممکنه شما لازم باشه روی موقعیت خاصی از کنترلی کلیک کنید تا Click حساب بشه، شاید لازمه شرایط خاصی باشه تا Click رخ بده. پس لازمه که OnClick ای باشه که بتوانید مراحل رخ دادن رخداد Click رو تغییر بدید. اگه OnClick ای در کار نبود یا Virtual نبود، تغییر دادن روال Click برای Control های سفارشی سخت میشد. همه On ها همینطور هستند.

سلامی مجدد
ممنون استاد علی
الان من توی رویداد کلیک در فرم ، اینو نوشتم :

کد:
        private void FormTest_Click(object sender, EventArgs e)
        {
            MessageBox.Show("FormTest_Click");
        }

در رویداد کلیک برای یه دکمه ای ، اینو :


کد:
        private void button19_Click(object sender, EventArgs e)
        {
            MessageBox.Show("button19_Click");
        }

و در همون کلاس فرم ام ، متد OnClick را اورراید کردم و کد زیر رو نوشتم :


کد:
        protected override void OnClick(EventArgs e)
        {
            MessageBox.Show("OnClick in override");
            base.OnClick(e);
        }

برای قضیه ی رویداد فرم ، درست عمل میکنه . یعنی وقتی که روی فرم کلیک میکنم ، اول متد اورراید شده ی OnClick در کلاس فرم (کد بالا) ، اجرا میشه و درصورت فراخونی متد base.OnClick(e) ، رویداد (یا در واقع تابع) FormTest_Click که به رویداد کلیک متصل شد ، فراخونی میشه . و اگه هم متد base.OnClick(e) درون متد اورراید شده ی OnClick در کلاس فرم برگردونده نشه ، رویداد FormTest_Click اجرا نمیشه (که درست هم هست)
ولی چرا این اعمال ، برای رویداد کلیک مربوط به button19 ، کار نمیکنه؟ یعنی روی اون دکمه که کلیک میکنم ، متد اورراید شده ی OnClick در کلاس فرم (کد بالا) اصلا اجرا نمیشه و چی کار باید کرد که اجرا بشه؟
 

the_king

مدیرکل انجمن
سلام. ممنون
استاد علی ، اینو از یه جای دیگه هم پرسیدم (از استاد آرمین) ، گفتش بعد از اولین فراخونی GC.Collect() ، متد GC.WaitForPendingFinalizers() رو باید صدا بزنم و بعد دوباره متد GC.Collect() رو . یعنی کد درستش اینه :


کد:
            int b = 300000;
            Button[] a = new Button[b];


            for (int i = 0; i < a.Length; i++)
            {
                a[i] = new Button();
            }
            for (int i = 0; i < a.Length; i++)
            {
                a[i] = null;
            }


            a = null;
       
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

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

the_king

مدیرکل انجمن
سلامی مجدد
ممنون استاد علی
الان من توی رویداد کلیک در فرم ، اینو نوشتم :

کد:
        private void FormTest_Click(object sender, EventArgs e)
        {
            MessageBox.Show("FormTest_Click");
        }

در رویداد کلیک برای یه دکمه ای ، اینو :


کد:
        private void button19_Click(object sender, EventArgs e)
        {
            MessageBox.Show("button19_Click");
        }

و در همون کلاس فرم ام ، متد OnClick را اورراید کردم و کد زیر رو نوشتم :


کد:
        protected override void OnClick(EventArgs e)
        {
            MessageBox.Show("OnClick in override");
            base.OnClick(e);
        }

برای قضیه ی رویداد فرم ، درست عمل میکنه . یعنی وقتی که روی فرم کلیک میکنم ، اول متد اورراید شده ی OnClick در کلاس فرم (کد بالا) ، اجرا میشه و درصورت فراخونی متد base.OnClick(e) ، رویداد (یا در واقع تابع) FormTest_Click که به رویداد کلیک متصل شد ، فراخونی میشه . و اگه هم متد base.OnClick(e) درون متد اورراید شده ی OnClick در کلاس فرم برگردونده نشه ، رویداد FormTest_Click اجرا نمیشه (که درست هم هست)
ولی چرا این اعمال ، برای رویداد کلیک مربوط به button19 ، کار نمیکنه؟ یعنی روی اون دکمه که کلیک میکنم ، متد اورراید شده ی OnClick در کلاس فرم (کد بالا) اصلا اجرا نمیشه و چی کار باید کرد که اجرا بشه؟
شما کلیک روی پنجره دکمه button19 رو مرتبط میدونید با کلیک روی پنجره فرم؟ خوب اینا که اصلا ربطی بهم ندارند. پنجره هاشون سوا است، رخداد هاشون سواست، Message هاشون سوا است. مادامی که دکمه Enable باشه یا بصورت فنی پنجره ای کلیک پذیر باشه پنجره زیرینش کلیک رو دریافت نمی کنه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
شما کلیک روی پنجره دکمه button19 رو مرتبط میدونید با کلیک روی پنجره فرم؟ خوب اینا که اصلا ربطی بهم ندارند. پنجره هاشون سوا است، رخداد هاشون سواست، Message هاشون سوا است. مادامی که دکمه Enable باشه یا بصورت فنی پنجره ای کلیک پذیر باشه پنجره زیرینش کلیک رو دریافت نمی کنه.

ممنون استاد علی . درباره ی جواب GC ، در حال خوندن هستم
-------------------------
میدونم مجزا هستن
ولی من متد OnClick (که در کلاس Control بصورت Virtual تعریف شده) را که در کلاس فرم ام (FormTest) اورراید میکنم ، وابسته به شی خاصی نیست . یعنی این طور نیست که این متد OnClick را فقط برای رویداد کلیک شی FormTest اورراید کنم
حالا اگه بخوام این متد OnClick را برای رویداد کلیک شی button19 اجرا بشه ، باید کد رو چجوری تغییر بدم؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
باز هم ناقصه و چیزی نیست که شما میخواهید، گرچه دلیل موجهی برای استفاده ازش نخواهید داشت ولی توضیحش اینه، GC داره مستقل برای خودش کار می کنه، دوره ای و به تدریج اشیاء بلا استفاده رو از روی تعداد ارجاع ها شناسایی می کنه و آزاد شون می کنه. پروسه اش هم مستقل ئه و به پروسه برنامه شما کاری نداره. حالا وقتی شما درخواست Collect می کنید، GC تلاش می کنه که مواردی که تا اون لحظه شناسایی شده رو آزاد کنه و به این معنی نیست که برای شناسایی موارد جدید وقت صرف کنه و به این معنی هم نیست که Collect نخ برنامه شما رو متوقف کنه تا وقتی که کارش تموم بشه. اون WaitForPendingFinalizers اینجا نقش اش اینه که تا وقتی که GC در حال کاری مثل Collect هست نخ برنامه شما رو منتظر نگه داره. نه به این معنی ئه که GC رو مجبور به تلاش خاص اضافه ای بکنه و نه به معنی آزاد کردن حافظه های بیشتری ئه. فقط از این جهت کاربرد داره که آماری که میخواهید بعد از Collect رو بگیرید، بعد از این WaitForPendingFinalizers بگیرید تا اگه GC داشت کاری انجام میداد، آمار شامل اونها هم بشه. صرفا همینه. در حالت عادی وقتی شما Collect رو اجرا می کردید و بعد آمار می گرفتید فرصت خاصی نداده بودید که اول Collect تموم بشه و بعد آمار بگیرید، ولی وقتی WaitForPendingFinalizers اجرا شد منتظر میمونید تا کار تموم بشه. اون Collect دومی هم که نوشتید یه مورد اضافه و مستقل ئه که ربطی به این روال و توضیحات نداره. اگر شیء ای در Collect اول آزاد نشد احتمالا دلیلی برای آزاد شدن در Collect دومی هم نداره.

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

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

بالا