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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
خیلی ممنون استاد .
ای ای ای :green: جلوی چشمم بود ، من ندیدم . کلاس Parallel ، متدی بنام Invoke داره (Parallel.Invoke) که آرایه ای از دلیگیت Action را میگیره و بصورت موازی اجرا میکنه . :green: چه ساده . منم همین رو میخواستم . اما ای کاش بسط و توسعه اش میدادن چون دلیگیت Action ، نه چیزی رو به عنوان ورودی میگیره و نه خروجی داره . حالا خروجی هیچ چی اما ای کاش یه دلیگیت طراحی میکردن که حداقل یه پارامتر از نوع Object را به عنوان ورودی دریافت میکرد.
اما توی توضیحات متدهای Parallel (چه متد Invoke و چه For و Foreach) ، میگه ممکن هست بصورت موازی اجرا بشه . چرا از کلمه ی "ممکن است" و "شاید" استفاده کرده؟ چرا قطعی نگفته؟
 

the_king

مدیرکل انجمن
سلام
خیلی ممنون استاد .
ای ای ای :green: جلوی چشمم بود ، من ندیدم . کلاس Parallel ، متدی بنام Invoke داره (Parallel.Invoke) که آرایه ای از دلیگیت Action را میگیره و بصورت موازی اجرا میکنه . :green: چه ساده . منم همین رو میخواستم . اما ای کاش بسط و توسعه اش میدادن چون دلیگیت Action ، نه چیزی رو به عنوان ورودی میگیره و نه خروجی داره . حالا خروجی هیچ چی اما ای کاش یه دلیگیت طراحی میکردن که حداقل یه پارامتر از نوع Object را به عنوان ورودی دریافت میکرد.
اما توی توضیحات متدهای Parallel (چه متد Invoke و چه For و Foreach) ، میگه ممکن هست بصورت موازی اجرا بشه . چرا از کلمه ی "ممکن است" و "شاید" استفاده کرده؟ چرا قطعی نگفته؟
مثل تماس تلفنی برای درخواست تاکسی میمونه، شما می توانید هر موقعی زنگ بزنید و درخواست تاکسی کنید، ولی نمی توانید مطمئن باشید که هر موقع تماس گرفتید به هر تعداد که ماشین خواستید فورا ارسال میشه.
ممکنه به اون تعداد تاکسی موجود نباشه یا اصلا جواب ندن و مدتی معطل بشید. آژانس برای شما ماشینی رزرو نگه نداشته، سیستم عامل هم برای NET. منابع اش رو رزرو نگه نمیداره.
NET. نمیتونه در مورد منابع و درخواست هایی که پاسخگویی اش با سیستم عامل ئه نظر قطعی بده که هر وقت درخواست کرد به تعداد کافی موجود ئه. طبعا Parallel هم نمیتونه انتظار داشته باشه که با مکث مشکل حل بشه. یعنی اونقدر صبر کنه که همه منابع مورد نیاز یکجا در اختیارش قرار بگیره، شاید هیچوقت سیستم عامل اینقدر دست و دلبازی نکنه.
 

Arnika Goli

New Member
در مورد تب کنترل
چجوری میشه وقتی برنامه باز میشه تب اول نمایش داده نشه تب دوم نمایش داده بشه؟
کدی هست که تو رویداد لود فرم بنویسم که اینکارو انجام بده؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
استاد ، مبحثی در سی شارپ (و کلا دات نت) که برای یادگیری پیشنهاد میکنید (ترجیحا از لیست مباحثی که در زیر میگم) ، چیه؟ یه مبحثی میخوام یاد بگیرم که علاوه بر اینکه در پروژه ها (ترجیحا پروژه های جاری ، یعنی پروژه ی "پشتیبانگیر طلوع" و پروژه ی "اتوران طلوع") کاربرد داشته باشه ، کلا هم مبحث مهم و مفیدی باشه که کلا به کارم بیاد .
مباحثی مثل چند نخی (منظورم ، ارتباط برقرار کردن داده ها در نخ هاست که نمیدونم) ، برنامه نویسی موازی (باز هم ارتباط برقرار کردن داده ها بین شون مد نظرم هست) ، Regex .
در وهله ی بعد ، که در الویت دوم فکر کنم قرار بگیرن ، مباحث xml و بعد زامارین و شاید هم تکنولوژی های مربوط به وب .
Entity Framework که گفتین مزایای چندانی نداره بنابراین من ادامه اش نمیدم ..

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

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

the_king

مدیرکل انجمن
استاد ، مبحثی در سی شارپ (و کلا دات نت) که برای یادگیری پیشنهاد میکنید (ترجیحا از لیست مباحثی که در زیر میگم) ، چیه؟ یه مبحثی میخوام یاد بگیرم که علاوه بر اینکه در پروژه ها (ترجیحا پروژه های جاری ، یعنی پروژه ی "پشتیبانگیر طلوع" و پروژه ی "اتوران طلوع") کاربرد داشته باشه ، کلا هم مبحث مهم و مفیدی باشه که کلا به کارم بیاد .
مباحثی مثل چند نخی (منظورم ، ارتباط برقرار کردن داده ها در نخ هاست که نمیدونم) ، برنامه نویسی موازی (باز هم ارتباط برقرار کردن داده ها بین شون مد نظرم هست) ، Regex .
در وهله ی بعد ، که در الویت دوم فکر کنم قرار بگیرن ، مباحث xml و بعد زامارین و شاید هم تکنولوژی های مربوط به وب .
Entity Framework که گفتین مزایای چندانی نداره بنابراین من ادامه اش نمیدم ..
به نظر من چیزی که نمیدونین کی لازمتون میشه رو بذارید کنار، تعداد مواردی که ممکنه یک وقتی لازم بشه خیلی خیلی زیاده و عمر آدمیزاد محدود ئه. احتمالش هست که تا بخواهید ازشون استفاده کنید منسوخ بشن یا اصلا لازم نشن، یادگرفتن زود موقع شون به نظر من بیفایده است، هدر دادن عمر ئه. روی چیزی تمرکز کنین که همین الان لازم دارین، یادگرفتن چیزی که الان برایتان کاربردی نداره وقت تلف کردنه . مثلا اگر الان برای Android یا IOS پروژه نمی نویسید، نه یادگرفتن Java بدرتون میخوره و نه Xamarin. هر وقت لازم شد همچین کاری انجام بدید اونوقت وقتش شده که زمان صرف کنید و یاد بگیرید. هر زمان درگیر پردازش رشته های ورودی شدید Regex رو یادبگیرید، چون خیلی برای اینکار مفیده، اما به این معنی نیست که پس الان باید یاد بگیریدش. هر زمان با کدی که خودتون نوشتید یک پردازش سنگین مثل رمز گشایی از فایل داشتید یا یک codec ویدئویی جدید اختراع کردید، اونوقت پردازش موازی بکارتون میاد، وگرنه نه. البته برای پردازش های سنگین زبان #C انتخاب خوبی نیست، توان پردازنده رو میگیرید ولی استفاده مفیدش کمه، بخش قابل توجهی اش هدر میره.

و اینکه استاد چرا زمان ساخت نخ های متفاوت ، میتونیم به نخ جدید ، پارامتر ورودی ارسال کنیم اما زمانی که تابعی را بصورت موازی میخوایم فراخونی کنیم ، براش قابلیت ارسال پارامتر نذاشتن؟
محدودیتی که مربوط به Parallel باشه نیست، ظاهر Action اونطوریه، وقتی نمیدونه Action چند تا پارامتر ورودی و با چه نوع داده ای داره ظاهر کلاسش همون ریختی میشه دیگه.
مثال های متعددی میشه زد :
کد:
        private void button1_Click(object sender, EventArgs e)
        {
            var actions = new Action<string>[] { MyAction1, MyAction2 };
            Parallel.ForEach(actions, action => action("any message"));
        }

        private static void MyAction1(string message)
        {
            MessageBox.Show("Action 1: " + message);
        }

        private static void MyAction2(string message)
        {
            MessageBox.Show("Action 2: " + message);
        }

کد:
        private void button1_Click(object sender, EventArgs e)
        {
            Parallel.Invoke(
            () =>
            {
                MyAction1("any message");
            }
            , () =>
            {
                MyAction2("any message");
            });
        }

        private static void MyAction1(string message)
        {
            MessageBox.Show("Action 1: " + message);
        }

        private static void MyAction2(string message)
        {
            MessageBox.Show("Action 2: " + message);
        }

کد:
        private void button1_Click(object sender, EventArgs e)
        {
            Parallel.For(0, 2, i =>
            {
                MyAction(i, "any message");
            });
        }

        private static void MyAction(long i, string message)
        {
            MessageBox.Show($"Action {i + 1}: {message}");
        }
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
به نظر من چیزی که نمیدونین کی لازمتون میشه رو بذارید کنار، تعداد مواردی که ممکنه یک وقتی لازم بشه خیلی خیلی زیاده و عمر آدمیزاد محدود ئه. احتمالش هست که تا بخواهید ازشون استفاده کنید منسوخ بشن یا اصلا لازم نشن، یادگرفتن زود موقع شون به نظر من بیفایده است، هدر دادن عمر ئه. روی چیزی تمرکز کنین که همین الان لازم دارین، یادگرفتن چیزی که الان برایتان کاربردی نداره وقت تلف کردنه . مثلا اگر الان برای Android یا IOS پروژه نمی نویسید، نه یادگرفتن Java بدرتون میخوره و نه Xamarin. هر وقت لازم شد همچین کاری انجام بدید اونوقت وقتش شده که زمان صرف کنید و یاد بگیرید. هر زمان درگیر پردازش رشته های ورودی شدید Regex رو یادبگیرید، چون خیلی برای اینکار مفیده، اما به این معنی نیست که پس الان باید یاد بگیریدش. هر زمان با کدی که خودتون نوشتید یک پردازش سنگین مثل رمز گشایی از فایل داشتید یا یک codec ویدئویی جدید اختراع کردید، اونوقت پردازش موازی بکارتون میاد، وگرنه نه. البته برای پردازش های سنگین زبان #C انتخاب خوبی نیست، توان پردازنده رو میگیرید ولی استفاده مفیدش کمه، بخش قابل توجهی اش هدر میره.

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

محدودیتی که مربوط به Parallel باشه نیست، ظاهر Action اونطوریه، وقتی نمیدونه Action چند تا پارامتر ورودی و با چه نوع داده ای داره ظاهر کلاسش همون ریختی میشه دیگه.
مثال های متعددی میشه زد :
کد:
        private void button1_Click(object sender, EventArgs e)
        {
            var actions = new Action<string>[] { MyAction1, MyAction2 };
            Parallel.ForEach(actions, action => action("any message"));
        }

        private static void MyAction1(string message)
        {
            MessageBox.Show("Action 1: " + message);
        }

        private static void MyAction2(string message)
        {
            MessageBox.Show("Action 2: " + message);
        }

کد:
        private void button1_Click(object sender, EventArgs e)
        {
            Parallel.Invoke(
            () =>
            {
                MyAction1("any message");
            }
            , () =>
            {
                MyAction2("any message");
            });
        }

        private static void MyAction1(string message)
        {
            MessageBox.Show("Action 1: " + message);
        }

        private static void MyAction2(string message)
        {
            MessageBox.Show("Action 2: " + message);
        }

کد:
        private void button1_Click(object sender, EventArgs e)
        {
            Parallel.For(0, 2, i =>
            {
                MyAction(i, "any message");
            });
        }

        private static void MyAction(long i, string message)
        {
            MessageBox.Show($"Action {i + 1}: {message}");
        }

ممنون استاد .
اینها را میدونم .
منظورم اینه که چرا برای متد Parallel.Invoke از دلیگیت Action که هیچ ورودی ای نمیگیره استفاده کردن؟ چرا از یه دلیگیت دیگه ای که ورودی بگیره (مثل متد سازنده ی کلاس Thread که از دلیگیت ParameterizedThreadStart استفاده میکنه برای ارسال ورودی) استفاده نکردن؟
 

the_king

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

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

ممنون استاد .
اینها را میدونم .
منظورم اینه که چرا برای متد Parallel.Invoke از دلیگیت Action که هیچ ورودی ای نمیگیره استفاده کردن؟ چرا از یه دلیگیت دیگه ای که ورودی بگیره (مثل متد سازنده ی کلاس Thread که از دلیگیت ParameterizedThreadStart استفاده میکنه برای ارسال ورودی) استفاده نکردن؟
گفتم که، ParameterizedThreadStart یک حالت خاص ئه که یک پارامتر داره از نوع object. اگر تعداد پارامتر ها بیشتر از یکی باشه یا نوع داده دیگری باشه دیگه ParameterizedThreadStart با اون تطابق نداره.
نیومدن برای تعداد پارامتر های بیشتر ParameterizedThreadStart2 و ParameterizedThreadStart3 و ... رو بسازن، منطقی نیست.
در <Action<T هم یک پارامتر ورودی T داره، مثلا <Action<string . چند تا پارامتر که نیست. برای Action در NET. تا تعریف 16 تا پارامتری اش هم هست. نمیشه که بیان بخاطر Action های چند پارامتری برای هر متد 17 جور متد با پارامتر و بی پارامتر بسازن که هر کدوم یکجور <... ,Action<T1, T2, T3 با تعدادی پارامتر قبول کنه. منطقی نیست. بجاش با یک متد و یک Action کلی این امکان رو به برنامه نویس دادن که هر جور که دلش خواست با هر تعداد پارامتر و هر نوع داده ای Action اش رو معرفی کنه. این خیلی ساده تر از اینه که بیان 17 جورش رو بسازن، خود متد ها همیطوری حالت های مختلفی دارن، با اون 17 حالت ترکیب بشه دیگه فاجعه میشه.
 

SajjadKhati

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

خیلی ممنون استاد

نظرم همونه که گفتم، اگر فکر می کنید قراره کاری رو 6 ماه بعد شروع کنید هم الان برای یادگیری موارد مربوط به اون زوده. الان چیزی رو یادبگیرید که دارید همین حالا انجامش میدید.


گفتم که، ParameterizedThreadStart یک حالت خاص ئه که یک پارامتر داره از نوع object. اگر تعداد پارامتر ها بیشتر از یکی باشه یا نوع داده دیگری باشه دیگه ParameterizedThreadStart با اون تطابق نداره.
نیومدن برای تعداد پارامتر های بیشتر ParameterizedThreadStart2 و ParameterizedThreadStart3 و ... رو بسازن، منطقی نیست.
در <Action<T هم یک پارامتر ورودی T داره، مثلا <Action<string . چند تا پارامتر که نیست. برای Action در NET. تا تعریف 16 تا پارامتری اش هم هست. نمیشه که بیان بخاطر Action های چند پارامتری برای هر متد 17 جور متد با پارامتر و بی پارامتر بسازن که هر کدوم یکجور <... ,Action<T1, T2, T3 با تعدادی پارامتر قبول کنه. منطقی نیست. بجاش با یک متد و یک Action کلی این امکان رو به برنامه نویس دادن که هر جور که دلش خواست با هر تعداد پارامتر و هر نوع داده ای Action اش رو معرفی کنه. این خیلی ساده تر از اینه که بیان 17 جورش رو بسازن، خود متد ها همیطوری حالت های مختلفی دارن، با اون 17 حالت ترکیب بشه دیگه فاجعه میشه.

آها
یعنی وقتی گفت شی ای نوع دلیگیت System.Action بده ، میتونیم شی ای از دلیگیت System.Action<T> و ... هم بدیم؟
دلیگیت ها فقط این طورن؟ روندشون چجوری هه؟
آخه مثل کلاس ها نیستن که مثلا نوع داده ای پدر را بدن اما ما بتونیم شی ای از فرزندشون بدیم.
در دلیگیت ها ، فضای نام و اون دلیگیت هه مهمه؟ یعنی وقتی میگه شی ای از System.Action بده ، ما میتونیم شی ای از هر دلیگیتی که تحت System.Action هست (چه با انواع مختلف جنریک ها و چه بدون جنریک) هست را بدیم؟
اگه این طوره ، چه خوب . پس چرا متد سازنده ی کلاس Thread را براش این جور دلیگیت در نظر نگرفتن؟ این جوری که بهتره .
 

the_king

مدیرکل انجمن
یعنی وقتی گفت شی ای نوع دلیگیت System.Action بده ، میتونیم شی ای از دلیگیت System.Action<T> و ... هم بدیم؟
نه. <= رو دارید اشتباه تفسیر میکنید، = نیست. ما delegate نمیدیم، متدی که اجرا میشه رو تعریف می کنیم. delegate ها حتی اگر مشابه هم باشند، متفاوت هستند، مثل دو تا کلاس که اگر کدشون شبیه هم باشه همچنان دو کلاس متفاوت هستند. نمیشه متد یک delegate رو به تعریف دیگری تحمیل کرد. اینطوری نیست که Action بخواد و شما <Action<T1,T2 بدید و اونم بگه مرسی.
مثالی که براتون زدم رو با دقت ببینید، دیدید در کد اول چطور <Action<string فراخوانی شد؟ به اون <= توجه کنید، ما <= رو داریم، نه =
ما داریم Action بدون پارامتر رو بصورت یک متد تعریف می کنیم که فلان متد با پارامتر رو اجرا می کنه.
من الان کد سوم رو که با { و } بود به کد اول نزدیک می کنم و به همون حالت می نویسم که ببینید ما در i که یک مقدار صحیح بدون اعشار ئه و ربطی به delegate نداره، delegate قرار ندادیم :
کد:
        private void button1_Click(object sender, EventArgs e)
        {
            Parallel.For(0, 2, i => MyAction(i, "any message"));
        }

        private static void MyAction(long i, string message)
        {
            MessageBox.Show($"Action {i + 1}: {message}");
        }
مجددا بررسیش کنید و اگه باز سوال پیش اومد بپرسید، چون سایر سوالات تون هم بر اساس همون تفسیر اشتباه ئه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
نه. <= رو دارید اشتباه تفسیر میکنید، = نیست. ما delegate نمیدیم، متدی که اجرا میشه رو تعریف می کنیم. delegate ها حتی اگر مشابه هم باشند، متفاوت هستند، مثل دو تا کلاس که اگر کدشون شبیه هم باشه همچنان دو کلاس متفاوت هستند. نمیشه متد یک delegate رو به تعریف دیگری تحمیل کرد. اینطوری نیست که Action بخواد و شما <Action<T1,T2 بدید و اونم بگه مرسی.
مثالی که براتون زدم رو با دقت ببینید، دیدید در کد اول چطور <Action<string فراخوانی شد؟ به اون <= توجه کنید، ما <= رو داریم، نه =
ما داریم Action بدون پارامتر رو بصورت یک متد تعریف می کنیم که فلان متد با پارامتر رو اجرا می کنه.
من الان کد سوم رو که با { و } بود به کد اول نزدیک می کنم و به همون حالت می نویسم که ببینید ما در i که یک مقدار صحیح بدون اعشار ئه و ربطی به delegate نداره، delegate قرار ندادیم :
کد:
        private void button1_Click(object sender, EventArgs e)
        {
            Parallel.For(0, 2, i => MyAction(i, "any message"));
        }

        private static void MyAction(long i, string message)
        {
            MessageBox.Show($"Action {i + 1}: {message}");
        }
مجددا بررسیش کنید و اگه باز سوال پیش اومد بپرسید، چون سایر سوالات تون هم بر اساس همون تفسیر اشتباه ئه.

سلامی مجدد
خیلی ممنون استاد
از عملگر لامبدا استفاده کردید دیگه؟ میدونم . با این عملگر آشنا ام .
من تازه متوجه شدم . در مثالی که در صفحه ی قبل از Parallel.For زدم ، برای متد اش پارامترِ par در نظر گرفتم اما موقع اجرا ، پارامتری براش نفرستادم . نمیدونم چجوری باید براش در اون مثال (بدون استفاده از عملگر لامبدا) پارامتر بفرستم .
الان استاد ، شما همین مثال تون را با استفاده از دلیگیت مینویسین؟ یعنی دلیگیتی تعریف کنین و اون را توی متغییر بریزین و در پارامتر متد Parallel.For تون، پارامتر i (مثل مثال بالای تون) را به این دلیگیت ارسال کنید . من نمیدونم با استفاده از دلیگیت ، چجوری این کار انجام میشه .
بعد اینکه من تازه متوجه شدم . وقتی از متدهای کلاس Parallel استفاده میکنیم ، ممکنه که در همون نخ اصلیِ برنامه مون هم کد اجرا بشه . ای کاش همه را در نخ دیگه میبرد . یعنی حتی تضمینی نیست که کد را در نخ جدیدی اجرا کنه .
بعد اینکه علامت $ قبل از رشته را فراموش کردم . برای چی بود؟
به هر حال اینکه برای دلیگیتی که برای متد Parallel.Invoke استفاده میکنیم (همونطور که در مثال شما هم هست) ، نمیشه پارامتری در نظر گرفت و ارسال کرد دیگه . درسته؟
اگه درسته ، خوب باز هم رسیدیم به سئوال اولم (سئوال پست 1427) :

منظورم اینه که چرا برای متد Parallel.Invoke از دلیگیت Action که هیچ ورودی ای نمیگیره استفاده کردن؟ چرا از یه دلیگیت دیگه ای که ورودی بگیره (مثل متد سازنده ی کلاس Thread که از دلیگیت ParameterizedThreadStart استفاده میکنه برای ارسال ورودی) استفاده نکردن؟
 
آخرین ویرایش:

the_king

مدیرکل انجمن
سلامی مجدد
خیلی ممنون استاد
از عملگر لامبدا استفاده کردید دیگه؟ میدونم . با این عملگر آشنا ام .
من تازه متوجه شدم . در مثالی که در صفحه ی قبل از Parallel.For زدم ، برای متد اش پارامترِ par در نظر گرفتم اما موقع اجرا ، پارامتری براش نفرستادم . نمیدونم چجوری باید براش در اون مثال (بدون استفاده از عملگر لامبدا) پارامتر بفرستم .
الان استاد ، شما همین مثال تون را با استفاده از دلیگیت مینویسین؟ یعنی دلیگیتی تعریف کنین و اون را توی متغییر بریزین و در پارامتر متد Parallel.For تون، پارامتر i (مثل مثال بالای تون) را به این دلیگیت ارسال کنید . من نمیدونم با استفاده از دلیگیت ، چجوری این کار انجام میشه .
Action یک delegate ئه و Parellel برای استفاده از delegete ای به نام Action طراحی شده. اگر منظور شما این باشه که delegate ای بجز Action تعریف کنیم و جایگزین Action کنیم در همون پست قبل گفتم که "نمیشه متد یک delegate رو به تعریف دیگری تحمیل کرد."، حتی اگر تعاریف مشابه هم باشند. از طرف دیگه متوجه نمیشم چرا نباید از عملگر Lambda استفاده کنید.

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

بعد اینکه علامت $ قبل از رشته را فراموش کردم . برای چی بود؟
مشخص کردن فرمت رشته بصورت درجا، نه مثل String.Format که پارامتر ها بعد رشته مشخص میشن. هرجا در رشته جای درج پارامتری است با {} مقدارش وارد میشه.
string interpolation (C# reference) $

به هر حال اینکه برای دلیگیتی که برای متد Parallel.Invoke استفاده میکنیم (همونطور که در مثال شما هم هست) ، نمیشه پارامتری در نظر گرفت و ارسال کرد دیگه . درسته؟
اگه درسته ، خوب باز هم رسیدیم به سئوال اولم (سئوال پست 1427) :

منظورم اینه که چرا برای متد Parallel.Invoke از دلیگیت Action که هیچ ورودی ای نمیگیره استفاده کردن؟ چرا از یه دلیگیت دیگه ای که ورودی بگیره (مثل متد سازنده ی کلاس Thread که از دلیگیت ParameterizedThreadStart استفاده میکنه برای ارسال ورودی) استفاده نکردن؟
باز هم رسیدیم به پاسخم در پست 1428. تعداد Action های تعریف شده 17 تا است، از صفر پارامتری تا 16 پارامتری. با همین یک Action بدون پارامتر، 12 متد Parallel.For و 20 تا متد Parallel.ForEach و 2 تا متد Parallel.Invoke داریم که جمعا میشه 34 متد. کمه؟ حالا شما میگید چرا بجای 34 متد صرفا برای بدون پارامتر، برای حداکثر یک پارامتری 68 متد یا برای تا 16 پارامتری 578 متد رو تعریف نکردند؟ خوب به نظرشون اضافی و غیر منطقی است. عملا که دیدید با همون Action بدون پارامتر بدون مشکل و زحمت هر تعداد پارامتری رو می توانیم به هر متد دلخواهی ارسال کنیم. ما که نمی خواهیم delegate اجرا کنیم، ما متد اجرا می کنیم.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
باز هم رسیدیم به پاسخم در پست 1428.
تعداد Action های تعریف شده 17 تا است، از صفر پارامتری تا 16 پارامتری. با همین یک Action بدون پارامتر، 12 متد Parallel.For و 20 تا متد Parallel.ForEach و 2 تا متد Parallel.Invoke داریم که جمعا میشه 34 متد. کمه؟ حالا شما میگید چرا بجای 34 متد صرفا برای بدون پارامتر، برای حداکثر یک پارامتری 68 متد یا برای تا 16 پارامتری 578 متد رو تعریف نکردند؟

خیلی ممنون استاد .
بذارید جواب سئوال هاتون را نامنظم بدم . حس میکنم یه مسائلی این وسط قر و قاتی شد که باعث میشه منظور همدیگه را درک نکنیم .
من به اورلود متدهای Parallel کاری ندارم . تا به این لحظه ، فقط متد Parallel.Invoke را در نظر بگیرید . هر اورلودی از این متد ، فقط دلیگیت Action را میگیره .حالا من میگم که چطوره که متد سازنده ی کلاس Thread ، دلیگیت ای از نوع ParameterizedThreadStart (که یه object رو به عنوان ورودی این دلیگیت و متد میپذیره) را قرار دادن تا برنامه نویس بتونه موقع اجرای نخ جدید ، یه پارامتری به نخ جدیدش ارسال کنه اما در این متدِ Parallel.Invoke ، چرا از دلیگیت ای (دلیگیتِ Action) استفاده کردن که برنامه نویس نتونه ورودی ای براش ارسال کنه؟
همونطور که میدونید و کدی هم که در پست 1426نوشتید (اشاره به همین حرفم داره) ، وقتی که از عملگر لامبدا (بجای تعریف شی دلیگیت) در متد Parallel.Invoke استفاده کردید ، به همین متد بی نام اش هم پارامتر ندادید .
یعنی من میگم بشه یه کدی نوشت که این جوری باشه :

کد:
        private void button1_Click(object sender, EventArgs e)
        {
            Parallel.Invoke(
            (object par) =>
            {
                MyAction1((string)par);
            }
            );
        }

        private static void MyAction1(string message)
        {
            MessageBox.Show("Action 1: " + message);
        }

یعنی عبارت لامبدا مون (یا کلا دلیگیت مون) ، ورودی بتونیم بهش بدیم .
الان سئوالم را قشنگ مطرح کردم؟ امید آن میرود که قشنگ ، مفهوم را رسونده باشم :green:

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

شما از داخل یک متدی که آرگومانی دریافت نمیکرد (متد بینامی که به عنوان عبارت لامبدا در نظر گرفتید) ، مقدار لیترالی (رشته ی "any message") را فرستادید .من میگم خود این متد (که حالا به عنوان عبارت لامبدا تعریف کردید بتونه مقداری را دریافت کنه.

Action یک delegate ئه و Parellel برای استفاده از delegete ای به نام Action طراحی شده.

میدونم.

اگر منظور شما این باشه که delegate ای بجز Action تعریف کنیم و جایگزین Action کنیم در همون پست قبل گفتم که "نمیشه متد یک delegate رو به تعریف دیگری تحمیل کرد."، حتی اگر تعاریف مشابه هم باشند.

نه . منظورم این نیست .
کلا دو تا سئوال دارم . یکی اش را که فکر کنم در پاراگراف بالا در همین پست ، قشنگ گفته باشم دیگه . ان شاء ا... که متوجه اش شده باشید .:) یکی دیگه را هم در زیر میگم.

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

چون من اون روش را بهتر درک میکنم .
یعنی الان نمیشه اون کدی که در پست 1426 دادید (که در همین پست هم نوشتم) ، بجای عملگر و عبارت لامبدا ، یک دلیگیت بسازید و اون رو اجرا کنید؟
یعنی الان مثلا به روشی که در کد زیر مینویسم ، موقع اجرای متد Parallel.For (در آرگومان سوم اش) ، مقدار par (در متد ActionHandler) را چجوری براش ارسال کنیم؟ (دقت کنید که نمیخوام از عبارت و عملگر لامبدا استفاده کنم . میخوام از همین روش زیر برم) :

کد:
        private void Button6_Click(object sender, EventArgs e)
        {
            Action<int> action = new Action<int>(this.ActionHandler);
            System.Threading.Tasks.Parallel.For(0, 1000000000, action);
            this.button6.Text = this.ParallelCounter.ToString();
        }

        private void ActionHandler(int par)
        {
            par++;
        }

شدنی هه؟
اگه آره ، کدش چجوری میشه؟
اگه نشدنی هه ، پس چرا مثل متد Thread.Start (که مقدار ورودی parameter را در نظر گرفت تا برای دلیگیتی که در متد سازنده ی Thread میسازیم ، بفرسته) ، برای ورودی متد Parallel.For ، یک پارامتر دیگه ای تعریف نکرد (مثل پارامتر parameter در متد Thread.Start) تا اون پارامتر را برای متد دلیگیت Action (سومین پارامتر در متد Parallel.For) بفرسته؟
متوجه ی سئوالم شدین؟

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


مشخص کردن فرمت رشته بصورت درجا، نه مثل String.Format که پارامتر ها بعد رشته مشخص میشن. هرجا در رشته جای درج پارامتری است با {} مقدارش وارد میشه.
string interpolation (C# reference) $

خیلی ممنون
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
بذارید جواب سئوال هاتون را نامنظم بدم . حس میکنم یه مسائلی این وسط قر و قاتی شد که باعث میشه منظور همدیگه را درک نکنیم .
من به اورلود متدهای Parallel کاری ندارم . تا به این لحظه ، فقط متد Parallel.Invoke را در نظر بگیرید . هر اورلودی از این متد ، فقط دلیگیت Action را میگیره .حالا من میگم که چطوره که متد سازنده ی کلاس Thread ، دلیگیت ای از نوع ParameterizedThreadStart (که یه object رو به عنوان ورودی این دلیگیت و متد میپذیره) را قرار دادن تا برنامه نویس بتونه موقع اجرای نخ جدید ، یه پارامتری به نخ جدیدش ارسال کنه اما در این متدِ Parallel.Invoke ، چرا از دلیگیت ای (دلیگیتِ Action) استفاده کردن که برنامه نویس نتونه ورودی ای براش ارسال کنه؟
از هر delegete ای، چه ParameterizedThreadStart و چه ThreadStart و چه Action و ... برای Thread یا Parallel.Invoke استفاده کنند، یک تعداد مشخص n پارامتر برای delegate تعریف شده. هر کسی هم میتونه بگه چرا n تا، من میخوام m تا پارامتر بهش ارسال کنم. برای برنامه نویس اهمیتی نداره، چون هر متد دلخواه خودش را با هر تعداد پارامتر میتونه داخل همون Action بدون پارامتر اجرا کنه، برنامه نویس برای چیزی که مشکل ایجاد نمی کنه نارضایتی نداره. ولی برای کسی که بخواد بازی دربیاره هر چیز ساده ای میتونه بهانه باشه، این بازی ئه. میگه یک مرغ دارم روزی دو تا تخم میذاره. چرا دو تا؟ پس چند تا؟ چهار تا. چرا چهار تا؟ پس چند تا؟ سه تا. چرا سه تا؟ ...

همونطور که میدونید و کدی هم که در پست 1426نوشتید (اشاره به همین حرفم داره) ، وقتی که از عملگر لامبدا (بجای تعریف شی دلیگیت) در متد Parallel.Invoke استفاده کردید ، به همین متد بی نام اش هم پارامتر ندادید .
یعنی من میگم بشه یه کدی نوشت که این جوری باشه :

کد:
        private void button1_Click(object sender, EventArgs e)
        {
            Parallel.Invoke(
            (object par) =>
            {
                MyAction1((string)par);
            }
            );
        }

        private static void MyAction1(string message)
        {
            MessageBox.Show("Action 1: " + message);
        }
شما یک متد تعریف کردید که پارامتر ورودی اش object par ئه، ولی وقتی این متد میخواد اجرا بشه هیچ ملاکی برای اینکه par چه مقدار باید داشته باشه هم در کد ندارید. فرض کنیم این کد ایرادی نداشت و قابل اجرا بود. object par رو خود NET. قراره به میل خودش مقدار بده؟ هر مقداری دلش خواست؟ null پیشفرض میداد خوب بود؟ به برنامه نویس ربطی نداره که مقدار par چی باشه؟ مقدار تصادفی باشه؟ نمیشه که اینجوری. شما باید تصمیم بگیرید که par مقدارش موقع اجرا چی باشه. Invoke که نمیتونه متدی رو اجرا کنه بدون اینکه بدونه چه مقداری برای پارامتر ورودی باید بهش داده بشه. اشکال کار شما اینه که توقع دارید MyAction1 به عنوان یک <Action<string در Parallel.Invoke اجرا بشه بدون اینکه بخواهید بهش بگید string ئه چه مقدار داره.

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

یعنی الان نمیشه اون کدی که در پست 1426 دادید (که در همین پست هم نوشتم) ، بجای عملگر و عبارت لامبدا ، یک دلیگیت بسازید و اون رو اجرا کنید؟
یعنی الان مثلا به روشی که در کد زیر مینویسم ، موقع اجرای متد Parallel.For (در آرگومان سوم اش) ، مقدار par (در متد ActionHandler) را چجوری براش ارسال کنیم؟ (دقت کنید که نمیخوام از عبارت و عملگر لامبدا استفاده کنم . میخوام از همین روش زیر برم) :

کد:
        private void Button6_Click(object sender, EventArgs e)
        {
            Action<int> action = new Action<int>(this.ActionHandler);
            System.Threading.Tasks.Parallel.For(0, 1000000000, action);
            this.button6.Text = this.ParallelCounter.ToString();
        }

        private void ActionHandler(int par)
        {
            par++;
        }

شدنی هه؟
اگه آره ، کدش چجوری میشه؟
اگه نشدنی هه ، پس چرا مثل متد Thread.Start (که مقدار ورودی parameter را در نظر گرفت تا برای دلیگیتی که در متد سازنده ی Thread میسازیم ، بفرسته) ، برای ورودی متد Parallel.For ، یک پارامتر دیگه ای تعریف نکرد (مثل پارامتر parameter در متد Thread.Start) تا اون پارامتر را برای متد دلیگیت Action (سومین پارامتر در متد Parallel.For) بفرسته؟
متوجه ی سئوالم شدین؟
خیلی ممنون
کد:
        private void button6_Click(object sender, EventArgs e)
        {
            var s = new string[] { "message 1", "message 2", "message 3" };
            var action = new Action<string>(ActionHandler);
            Parallel.ForEach(s, action);
        }

        private void ActionHandler(string par)
        {
            MessageBox.Show(par);
        }
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کد:
        private void button6_Click(object sender, EventArgs e)
        {
            var s = new string[] { "message 1", "message 2", "message 3" };
            var action = new Action<string>(ActionHandler);
            Parallel.ForEach(s, action);
        }

        private void ActionHandler(string par)
        {
            MessageBox.Show(par);
        }

خیلی ممنون استاد .
یه توضیحی درباره ی این کد میدین؟ واسم جای تعجب هه .
در این اورلود ، متد ForEach ، دو تا ورودی دریافت میکنه . یکی آرگومان s بهش دادید که به نظر میرسه فقط باید به عنوان شمارنده در نظر گرفته بشه تا به اندازه ی تعداد این آرایه ، بدنه یا همون آرگومان دوم یعنی action ، اجرا بشه . اما چرا اعضای آرایه ی s ، به عنوان ورودیِ دلیگیتِ action (یعنی پارامتر action در متد ActionHandler) فرستاده میشن؟!!
نحوه ی عملکردش چجوری هه؟
بعد اینکه اما باز هم ما بصورت مستقیم ، خودمون مقدار را ارسال نکردیم . یعنی آرایه را بهش دادین ، متد ForEach ، هر مقداری از اون آرایه را ارسال میکنه . اما اگه شما بخواین خودتون همیشه مثلا فقط مقدارِ ایندکسِ اول از آرایه را ارسال کنید . یا اصلا مقدار یک متغییر دیگه را ارسال کنید ، در این صورت چی کار میکنید؟ کاریش نمیشه کرد؟

تعریف طوری باشه که بتونه مقداری دریافت کنه، باشه، مثل کد شما تعریف کردن باشه، ولی مقدارش کجا مشخص بشه؟ وقتی مقدار پارامتر مشخص شدنی نباشه تعریف پارامتر به چه دردی میخوره؟

آی خدا اموات شما را بیامرزه استاد .
من هم الان توی چند پست ، دارم همین رو میگم دیگه و چند بار پرسیدم.
در کلاس Thread ، برای حل این مشکل ، متد Thread.Start ، برای همین قرار داده شد دیگه . اینکه اگه برنامه نویس بخواد مقداری رو به نخ جدیدش ارسال کنه ، از اورلود public void Start(object parameter) اش این کار را انجام بده . خوب ، چرا برای متدهای کلاس Parallel ، همچین پارامتری را در نظر نگرفتن تا مقدارش را ارسال کنن .
همین سئوالم ، که برابر با همین سئوال خودتونه که نقل قول کردم را الان توی پست قبلی پرسیدم .

از هر delegete ای، چه ParameterizedThreadStart و چه ThreadStart و چه Action و ... برای Thread یا Parallel.Invoke استفاده کنند، یک تعداد مشخص n پارامتر برای delegate تعریف شده. هر کسی هم میتونه بگه چرا n تا، من میخوام m تا پارامتر بهش ارسال کنم. برای برنامه نویس اهمیتی نداره، چون هر متد دلخواه خودش را با هر تعداد پارامتر میتونه داخل همون Action بدون پارامتر اجرا کنه، برنامه نویس برای چیزی که مشکل ایجاد نمی کنه نارضایتی نداره. ولی برای کسی که بخواد بازی دربیاره هر چیز ساده ای میتونه بهانه باشه، این بازی ئه. میگه یک مرغ دارم روزی دو تا تخم میذاره. چرا دو تا؟ پس چند تا؟ چهار تا. چرا چهار تا؟ پس چند تا؟ سه تا. چرا سه تا؟ ...

لازم به چند تا (آرگومان های ورودیِ مختلف) نیست استاد .
این سئوالی بود که من اوایل ، درباره ی قضیه ی نخ ها ازتون پرسیدم اگه یادتون باشه .
گفتم چرا توی کلاس Thread ، از یک Object فقط استفاده شد؟
قطعا همونطور که الان هم میدونین و جواب داده بودین این بود که لازم نیست چندین پارامتر تعریف بشه . همه ی اشیاء (آرایه ها و هر چیزی) داخل object قرار میگیرن پس اگه برنامه نویس ، چند آرگومان را خواست مقداردهی کنه ، میتونه از آرایه ها یا هر شی دیگه ای استفاده کنه .
خوب ، توی متد Parallel.Invoke هم یه دلیگیت ای در نظر میگرفتن که یه ورودی Object اگه میداشت ، مثل همون قضیه ، برای برنامه نویس کافی میبود.
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
یه توضیحی درباره ی این کد میدین؟ واسم جای تعجب هه .
در این اورلود ، متد ForEach ، دو تا ورودی دریافت میکنه . یکی آرگومان s بهش دادید که به نظر میرسه فقط باید به عنوان شمارنده در نظر گرفته بشه تا به اندازه ی تعداد این آرایه ، بدنه یا همون آرگومان دوم یعنی action ، اجرا بشه . اما چرا اعضای آرایه ی s ، به عنوان ورودیِ دلیگیتِ action (یعنی پارامتر action در متد ActionHandler) فرستاده میشن؟!!
چرا؟ چون اون ForEach طبق تعریفش کارش همینه. خوب <Action<T برای همین چیزا در متد تعریف شده دیگه. s صرفا به جهت s.Length که بکار نرفته، اگر صرفا عدد 3 معیار بود که بجاش از For استفاده می کردیم. اعضاء s همونطور که برای foreach دونه دونه پیمایش میشه در Parallel.ForEach پیمایش میشه. Parallel.ForEach میدونه که وقتی شما مجموعه ای از T ها رو بهش دادید، (مجموعه یا کلا هر <IEnumerable<T دیگری) باید یکی یکی اعضاء رو به <Action<T مشخص شده به عنوان پارامتر بده.

بعد اینکه اما باز هم ما بصورت مستقیم ، خودمون مقدار را ارسال نکردیم . یعنی آرایه را بهش دادین ، متد ForEach ، هر مقداری از اون آرایه را ارسال میکنه . اما اگه شما بخواین خودتون همیشه مثلا فقط مقدارِ ایندکسِ اول از آرایه را ارسال کنید . یا اصلا مقدار یک متغییر دیگه را ارسال کنید ، در این صورت چی کار میکنید؟ کاریش نمیشه کرد؟
اگر بخوام فقط اندیس اول آرایه رو بکار ببرم برای چی از ForEach استفاده کنم؟
ForEach مثل foreach ئه، قراره از شما مجموعه بگیره و عینا از اعضاء اون استفاده کنه، اگر قراره از اعضاء اون مجموعه استفاده نشه و مقادیر دیگری بکار بره چرا از ForEach استفاده می کنیم؟
اگر شما بخواهید به foreach بجای مقادیر یک مجموعه مقادیر دلخواه خودتون رو بدید چیکار می کنید؟ یا مجموعه دلخواه رو جدا میسازید و بهش می دهید یا میایید یک کلاس با پیاده سازی <IEnumerable<T میسازید که به هر شیوه دلخواهی از اعضاء مقدار خاصی جدا کنه. در ForEach هم دقیقا همین کار رو می توانید بکنید، یا مجموعه مستقل میسازید یا یک <IEnumerable<T اختصاصی.
اما اگر مقادیر اصلا ربطی به مجموعه ندارند و میخواهید دستی مقادیر دیگری مشخص کنید، دیگه نیازی به ForEach نداریم، می توانیم فرضا با For کار کنیم :
کد:
        private void button1_Click(object sender, EventArgs e)
        {
            Parallel.For(0, 3, (i) => MyAction($"any message {i + 1}"));
        }

        private static void MyAction(string message)
        {
            MessageBox.Show(message);
        }
یا اگه نمیخواهیم از Lambda استفاده کنیم :
کد:
        private void button1_Click(object sender, EventArgs e)
        {
            Parallel.For(0, 3, new Action<int>(DoAction));
        }

        private void DoAction(int i)
        {
            MyAction($"any message {i + 1}");
        }

        private static void MyAction(string message)
        {
            MessageBox.Show(message);
        }

آی خدا اموات شما را بیامرزه استاد .
شما چیکار به اموات من دارین؟

خوب ، توی متد Parallel.Invoke هم یه دلیگیت ای در نظر میگرفتن که یه ورودی Object اگه میداشت ، مثل همون قضیه ، برای برنامه نویس کافی میبود.
الان شما نمی توانید با Invoke پارامتری به متدی ارسال کنید؟ قبول. Action بدون پارامتر براتون کافی نیست؟ قبول. از Lambda نمی خواهید استفاده کنید؟ قبول. اما این دلیل نمیشه که چون شما نمی توانید و نمی خواهید پس امکانات NET. کافی نیست و برنامه نویسان با کمبود مواجه میشن. من و هر برنامه نویس دیگری با Invoke به هر تعدادی پارامتر که خواست به هر متدی که دلش خواست ارسال می کنه و دلیلی هم نمی بینه که بگه امکانات Invoke کافی نیست. اگر معیار کافی عقیده شخصی من یا شما باشه که دیگه جای بحث نداریم، شما عقاید خودتون رو دارید، من عقاید خودم رو، طراحان NET. هم عقاید خودشون رو. اما اگر معیار کافی محدودیت های حقیقی باشه، همون Action بدون پارامتر کافیه. برای شما کافی نیست؟ قبول می کنم. برای شما کافی نیست. چه اشکالی داره، این هم عقیده ای است، بحثی هم روی عقاید شخصی کسی ندارم.
کد:
        private void button1_Click(object sender, EventArgs e)
        {
            var actions = new Action[3];
            actions[0] = delegate ()
            {
                MyAction1("any message", 1);
            };
            actions[1] = delegate ()
            {
                MyAction2(Cursor.Position);
            };
            actions[2] = delegate ()
            {
                MyAction3(1.5, 3.4, 2);
            };
            Parallel.Invoke(actions);
        }

        private static void MyAction1(string message, int actionId)
        {
            MessageBox.Show($"Action {actionId}: {message}");
        }

        private static void MyAction2(Point p)
        {
            MessageBox.Show($"Action 2: {p.X},{p.Y}");
        }

        private static void MyAction3(double a, double b, double c)
        {
            MessageBox.Show($"Action 3: {Math.Pow(a * b, c):0.##}");
        }
 

SajjadKhati

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


استاد ، به نظرتون ، کنترل های مورد نیازم (مثل کمبوباکس و ...) را شخصی سازی کنم بهتره یا از همین نوع کنترل هایی که شرکت ها ، کمپوننت های آماده شو زدن استفاده کنم؟
شما توی پروژه هاتون ، خودتون وقت میذارید و کنترل های مورد نظرتون را در صورت نیاز ، شخصی سازی میکنید یا اینکه از کمپوننت های آماده ترجیح میدین استفاده کنین؟
 

the_king

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

SajjadKhati

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

خیلی ممنون
استاد ، میگم میخوام کمبوباکس را شخصی سازی کنم ، کد زیر را مینویسم اما متدهاش اجرا نمیشن (متد OnPaint اجرا نمیشه) با اونکه مقدار پروپرتی DrawMode برابر DrawMode.OwnerDrawFixed هه . فقط هم کمبوباکس پیش فرض را رسم میکنه :

کد:
    class CustomComboBox : ComboBox
    {
        public CustomComboBox()
        {
            this.DrawMode = DrawMode.OwnerDrawFixed;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            ButtonRenderer.DrawButton(e.Graphics, e.ClipRectangle, System.Windows.Forms.VisualStyles.PushButtonState.Default);
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            base.OnPaintBackground(pevent);
        }

    }

متد base.OnPaintBackground را هم چه اجرا کنم یا نکنم ، فرقی نداره.
چرا این جوری هه؟
مشکل از کجاست؟
 

the_king

مدیرکل انجمن
خیلی ممنون
استاد ، میگم میخوام کمبوباکس را شخصی سازی کنم ، کد زیر را مینویسم اما متدهاش اجرا نمیشن (متد OnPaint اجرا نمیشه) با اونکه مقدار پروپرتی DrawMode برابر DrawMode.OwnerDrawFixed هه . فقط هم کمبوباکس پیش فرض را رسم میکنه :

کد:
    class CustomComboBox : ComboBox
    {
        public CustomComboBox()
        {
            this.DrawMode = DrawMode.OwnerDrawFixed;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            ButtonRenderer.DrawButton(e.Graphics, e.ClipRectangle, System.Windows.Forms.VisualStyles.PushButtonState.Default);
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            base.OnPaintBackground(pevent);
        }

    }

متد base.OnPaintBackground را هم چه اجرا کنم یا نکنم ، فرقی نداره.
چرا این جوری هه؟
مشکل از کجاست؟
مشکل از اینجا است که راهنمای DrawMode رو نخوندید.
اصلا کاری با OnPaint یا OnPaintBackground نخواهید داشت، شما باید یک آیتم رو رسم کنید. هم در ListBox و هم در ComboBox از رخداد DrawItem استفاده می کنید. رجوع شود به :
ListBox های رنگارنگ و #1300 و 1298# و 1236# و ListBox.DrawItem Event و ComboBox.DrawItem
 

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

بالا