نمایش نتایج 1 تا 2 از 2

نام تاپیک: serialPort1_DataReceived و thread.sleep

Threaded View

پست قبلی پست قبلی   پست بعدی پست بعدی
  1. #2

    نقل قول: serialPort1_DataReceived و thread.sleep

    سلام
    از async await استفاده کنید :

    هنگ برنامه هنگام گرفتن سورس سایت

    اما در اون مثال ، 2 نکته را جایگزین کنید :
    اول اینکه سعی کنید بجای اون بخش از کد که در نخ جدید اجرا میشه را داده بودم ، یعنی بجای کد زیر در اون مثال :


    Task<string> httpDataTask = new Task<string>(new Func<string>(this.GetHttpData));
    httpDataTask.Start();


    از متدهای TaskFactory.StartNew یا از متد استاتیک Task.Run برای اجرای کدتوی در نخ جدید استفاده کنید :

    TaskFactory.StartNew Method (System.Threading.Tasks) | Microsoft Learn

    دوم و مهمتر اینکه سعی کنید این تیکه از کدها را وقتی بکار میبرید ، درون متدی بکار ببرید که نوع بازگشتی اش از Task یا Task<T> باشه .
    یعنی مثلِ اون مثال ، مستقیما کد بالا را درون رویداد ها (که خروجی ای ندارند و void هستند) ، بکار نبرید .
    چون حداقل اینکه برای مدیریت استثنا و خطاهایی که درونِ اون نخِ جدید اتفاق میافته ، نوع خروجی Task یا Task<T> بکار میاد .

    برای مدیریت استثنا و خطاها در نخ جدید هم به لینک زیر مراجعه کنید :

    مدیریت استثناء در نخ جدید

    برای اینکار (طبق مثال در لینک بالا) ، کافی هست که بخش await را درون try catch بذارید . اونجایی این کار را میکنید هم توی متدی باید باشه که خروجی اش از نوع Task یا Task<T> باشه .

    ----------

    یه مثال از این نکات بالا :


    private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
    long fibonacciValue = await this.FibonacciAsync(37);
    // کد مورد نظرتون برای اینکه بعد از اتمامِ اجرای نخ جدیدتون ، اجرا بشه را اینجا ، یعنی در پایینِ await بنویسید .
    if (fibonacciValue > -1)
    MessageBox.Show(fibonacciValue.ToString());
    }








    private async Task<long> FibonacciAsync(int number)
    {
    Task<long> fibonucciTask = Task.Factory.StartNew<long>(new Func<object, long>(this.Fibonacci), number);


    long fibonucciReturnValue = -1;
    try
    {
    fibonucciReturnValue = await fibonucciTask;
    // کد مورد نظرتون برای اینکه بعد از اتمامِ اجرای نخ جدیدتون ، اجرا بشه را اینجا ، یعنی در پایینِ await بنویسید .
    }
    catch (Exception exception)
    {
    MessageBox.Show(exception.Message);
    }


    return fibonucciReturnValue;
    }








    private long Fibonacci(object number)
    {
    int numberConverted = Convert.ToInt32(number);
    if (numberConverted == 0 || numberConverted == 1)
    return numberConverted;


    return this.Fibonacci(numberConverted - 1) + this.Fibonacci(numberConverted - 2);
    }


    که خروجیِ await را مستقیما میتونید به عنوان مقدار long در مثال بالا ، برگردونید .
    یعنی اگه متدی هم فقط از نوع Task باشه (یعنی Task<T> نباشه) ، دیگه اصلا return کردن ، لازم نداره .


    میشه در این سلسله مراتبی هم یه متدی باشه که فقط Task باشه و یعنی هیچ چی برنگردونه .
    یعنی مثلا رویداد کلیک در بالا ، یه متدی دیگه ای که در مثال بالا نیست و فرضا اسم اش MiddleMethod باشه که خروجی اش از نوع Task باشه (نه از نوع Task<T> یا Task<long>) را فراخوانی کنه .

    بنابراین این متد ، اصلا نیاز به استفاده از کلمه ی کلیدی return در بدنه اش نداره (ربطی به استفاده نکردن از کلمه ی کلیدیِ await نداره و باید ازش استفاده کنه . در واقع توصیه ی اکید میشه که تمام متدهایی که async هستند ، درون شون از await استفاده کنند) .

    و این متدِ MiddleMethod ، درون خودش ، متدِ FibonacciAsync در مثال بالا را فراخونی کنه که بقیه ی روال هاش مشخص هست .

    متد FibonacciAsync در بالا را بصورت خلاصه به شکل زیر هم میشه نوشت منتها در این حالت ، نمیشه از try catch درش استفاده کرد یا بعد از await اش ، کدی نوشت تا بعد از خاتمه ی اجرای نخ جدید ، اون کد اجرا بشه :


    private async Task<long> FibonacciAsync(int number)
    {
    return await Task.Factory.StartNew<long>(new Func<object, long>(this.Fibonacci), number);
    }


    ---------

    await هم کارکردش به این صورت هست که وقتی کنترل برنامه ، به کلمه ی کلیدی await میرسه ، اون Task ئه اجرا شده ای که بهش داده شد را منتظرش میمونه تا اجراش تمام بشه و بنابراین کدهایی که در پایینِ اش نوشته شدن را معلق میذاره (یه کاری شبیه به yield ها) و این کدها اجرا نمیشن تا اون Task خاتمه پیدا کنه ،

    و مخصوصا اینکه همچنین کنترلِ اجرای کدها را به استکِ متدِ قبلی هدایت میکنه (یعنی متد قبلی توی استک که فراخوانی کننده ی این متدی بود که توی این متد ، کلمه ی کلیدیِ await وجود داشت ، کنترلِ اجرای کدهای برنامه را به اون استکِ قبلیِ متد در اون نخ میبره) .
    یعنی کاری شبیه به return انجام میده (البته از لحاظ برگشتن به استک قبلی ، شبیه بهش هست وگرنه ادامه ی کدهاش بعد از خاتمه ی نخ اجرا میشه که این ، کار را return انجام نمیده) .

    -----------

    برای مدیریت دسترسی به داده ی واحد (مثلا دسترسی به متغییر سراسری ، یا دسترسی به متغییر محلی ای که اشاره گری به متغییر سراسری هست) درون دو یا چند نخ هم روش های متفاوتی که هر کدوم برای جایی کاربرد دارن ، هست اما یکی از رایج ترین شون ، استفاده از کلمه ی کلیدی lock هست .
    آخرین ویرایش به وسیله SajjadKhati : سه شنبه 02 اسفند 1401 در 08:32 صبح

تاپیک های مشابه

  1. تفاوت DoEvents و Thread.Sleep
    نوشته شده توسط samiasoft در بخش C#‎‎
    پاسخ: 3
    آخرین پست: شنبه 13 خرداد 1396, 10:26 صبح
  2. مشکل با Thread.Sleep
    نوشته شده توسط unrealword در بخش C#‎‎
    پاسخ: 5
    آخرین پست: یک شنبه 27 مهر 1393, 10:41 صبح
  3. مشکل در بکارگیری تابع System.Threading.Thread.Sleep()
    نوشته شده توسط SamaPic در بخش VB.NET
    پاسخ: 3
    آخرین پست: چهارشنبه 25 اردیبهشت 1392, 17:09 عصر
  4. عملکرد Thread.Sleep
    نوشته شده توسط PrinceDotNet در بخش ASP.NET Web Forms
    پاسخ: 3
    آخرین پست: دوشنبه 24 بهمن 1384, 17:18 عصر

قوانین ایجاد تاپیک در تالار

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