• Products
    مطابق با جستجوی شما محصولی یافت نشد. توجه فرمایید که در جستجو ترتیب عبارات وارد شده مهم می باشد.
    وبلاگ فیلترگذاری
    تصویر برای پست وبلاگ فرق Task.Run با Task.Factory.StartNew

    فرق Task.Run با Task.Factory.StartNew


    سوال:
    فرق Task.Run با Task.Factory.StartNew چیه؟ از کدومشون باید استفاده کنیم؟

    پاسخ:
    خود Task.Run پشت پرده از Task.Factory.StartNew استفاده میکنه و در واقع یه Wrapper روی اون هست که استفاده ازش رو ساده تر می‌کنه.
    علتش اینه که Task.Factory.StartNew امضا (overload) های متفاوتی داره که کار با اون رو انعطاف پذیر تر میکنه که همین انعطاف پذیری بیشتر باعث شده کار باهاش پیچیده تر باشه. مثلا وجود آپشن های بیشتری از جمله TaskCreationOptions و TaskScheduler که اجازه میده سفارشی سازی بیشتری انجام بدیم.

    همچنین با توجه به اینکه خروجی متد StartNew از نوع <Task<T هست، این نوع جنریک T درواقع خروجی همون delegate ایی که بهش پاس میدین. درنتیجه اگر delegate ورودی شما به متد StartNew، خودش از نوع Task باشه، خروجی نهایی متد StartNew میشه یک <Task<Task که در این حالت بایستی توسط متد Unwarp، اون تسک داخلی (inner task) رو بیرون بکشید و با اون کار بکنید
    از این رو تیم دات نت به جهت جلوگیری و مخفی کردن این پیچیدگی ها اومده Task.Run رو برای سناریو های پرکاربرد ایجاد کرده که این پیچیدگی ها رو داخل خودش مخفی میکنه

    جمع بندی اینکه همیشه از Task.Run به جای Task.Factory.StartNew استفاده کنید مگر اینکه نیاز به سفارشی سازی یا استفاده از حالت های خاص دارید (اون هم با آگاهی کامل) که توضیحش از حوصله این سوال خارجه
    جهت اطلاعات بیشتر مطالعه لینک زیر کمکتون میکنه
    ▪️Task.Run vs Task.Factory.StartNew


    (https://devblogs.microsoft.com/pfxteam/task-run-vs-task-factory-startnew/)🔸حالا که تا اینجای کار اومدید جا داره یه نکته دیگه هم بگم
    علاوه بر روش های بالا 2 روش دیگه برای ساخت یک Task وجود داره.
    1- نمونه سازی تسک توسط سازنده کلاس Task
    2- استفاده از کلاس TaskCompletionSource

    این دو روش کمتر عمومی بوده و معمولا نیاز نمیشه از این ها استفاده کنید. روش اول بسیار کم کاربرد هست و use-case های خاصی داره و باید با احتیاط و آگاهی ازش استفاده کنین.
    وقتی شما توسط Task.Run یا Task.Factory.StartNew استفاده میکنید، یک تسک برای شما ساخته میشه و بلافاصله Start میشه. درنتیحه Task ایی که به دست شما میرسه از قبل start شده و فراخوانی مجدد متد Start روی اون، باعث وقوع Exception میشه

    ولی وقتی توسط سازنده کلاس Task استفاده میکنید میتونین قبل از Start شدنش به اون نمونه ایجاد شده دسترسی پیدا کنین. و سپس باید به صورت دستی متد Start رو فراخوانی کنین تا Task اجرا بشه. هرچند فراخوانی دستی متد Start بدلیل Synchronization ایی که در پشت صحنه اعمال میشه (به دلیل جلوگیری از Start شدن همزمان توسط چندین Thread) دارای سربار هست

    کلاس TaskCompletionSource اما مکانیزمش کلا فرق میکنه. این کلاس وظیفه ساخت "و مدیریت" چرخه حیات یک Task رو به عهده داره.
    مثلا توسط متد های SetResult و SetException و SetCanceled (و نیز همین متد ها با پشوند TryXXX به جهت مدیریت همزمانی) این امکان رو به شما میده وضعیت تسک رو به یکی از این حالات تغییر بدید:
    "کنسل شده" یا "خطا رخ داده" یا "تکمیل شده با موفقیت (به همراه نتیجه خروجی اون)"
    از این روش معمولا برای تبدیل کد های قدیمی APM و EAP به TPL (روش جدید تر و توصیه شده مایکروسافت) استفاده میشه و یه use-case های خاصی که باید با احتیاط و آگاهی از استفاده بشه

    اطلاعات بیشتر:
    ▪️ (https://devblogs.microsoft.com/pfxteam/task-run-vs-task-factory-startnew/)Mechanisms for Creating Tasks
    (https://devblogs.microsoft.com/pfxteam/mechanisms-for-creating-tasks/)▪️ (https://devblogs.microsoft.com/pfxteam/task-run-vs-task-factory-startnew/)The Nature of TaskCompletionSource
    (https://devblogs.microsoft.com/pfxteam/the-nature-of-taskcompletionsourcetresult/)▪️ (https://devblogs.microsoft.com/pfxteam/task-run-vs-task-factory-startnew/)The danger of TaskCompletionSource class

    نظر خود را ارسال کنید

    back to top
    فیلترگذاری