منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب

نسخة كاملة : كيف أتمكن من إنتظار مهام متعددة Threading.Tasks.Task حتى تنتهي جميعها
أنت حالياً تتصفح نسخة خفيفة من المنتدى . مشاهدة نسخة كاملة مع جميع الأشكال الجمالية .
السلام عليكم ورحمة الله وبركاتة

تحياتي لل الأعضاء الكرام

بعد محاولات كثيرة لم أستطع أو أستوعب ما هو المطلوب لكي أتمكن من إنتظار عدة مهام ( Tasks )
اقوم في Loop بالإلتفاف على جدول يحتوي على معلومات عن ملفات موجودة على الإنترنت ( اسم الملف ، الرابط ، وما إلى ذلك )
في كل لفة أقوم بإنشاء Task
وأضيف هذا ال Task في مجموعة لكي أستطيع الوصول إليه فيما بعد لدواعي الإلغاء ومعرفة حالة ال Task
وفي نفس اللفة أقوم بتشغيل ال Task
ثم أنتقل إلى ال Row الذي يليه ، وهكذا مع كل السجلات لتحميل جميع الملفات في نفس الوقت


الآن لدي مجموعة تحتوي على كل ال Task التي تم تشغيلها
في أثناء الإلتفاف على الجدول ، تم تمرير TaskCancelTokenSource إلى كل Task
حتى أتمكن من عمل إلغاء للكل

كل المهام تعمل في الخلفية وهذا شيء جيد
لكن 
المشكلة أنني عندما أنفذ عمل الإلغاء بواسطة :
Sub Cancel
( Me.TaskCancelTokenSource.Cancel ) ، تنتهي عملية الإلغاء بسرعة ، ولكن ال Task مازال يعمل على تنفيذ أمر الإلغاء

حتى أن الرسالة :
MsgBox("All Tasks Completed...")
تظهر مباشرتاً قبل حتى أن تبداء أي مهمة.

أي ان الرسالة التي تبين إنتهاء أو إلغاء جميع المهام تظهر قبل الرسالة الموجودة في آخر كل مهمة.

حاولت كثيراً , جربت أكواد من مواقع لكن كلها تعمل بشكل مختلف لا يوجد كود يشبه الآخر , لم أجد مثال طبقته بنجاح.

كيف يمكنني إنتظار إنتهاء جميع المهام ( سواء أكان إنتظار حتى تنتهي كلها ) ( أو إنتظار تنفيذ أمر الإلغاء للجميع )


ملاحظة :
الوظيفة ( GetFileContent ) + ( DownloadFileAsync ) تعمل بشكل متزامن Synchronously ، بإستخدام ال Async )  modifier )

كود :
    Dim TaskList As New List(Of Task)
    Dim TaskCancelTokenSource As CancellationTokenSource


    Private Sub StartAllDownloadTasks()

        Me.TaskCancelTokenSource = New System.Threading.CancellationTokenSource

        For Each Row In Me.DownloadSourceDataTable

            If Row.T_IsActive Then

                Dim DownloadTask As New Task(Sub()
                                                 Me.GetFileContent(Row)
                                             End Sub, Me.TaskCancelTokenSource.Token)
                Me.TaskList.Add(DownloadTask)
                DownloadTask.RunSynchronously()

            End If

        Next


        Dim AllTasks = Task.WhenAll(Me.TaskList.ToArray)
        ' نتظار جميع المهام حتى تنتهي
        AllTasks.Wait()

        ' هذا الرسالة تظهر مباشرتاً ولا تنتظر إنتهاء جميع المهام
        MsgBox("All Tasks Completed...")

    End Sub

    Private Async Sub GetFileContent(Row As DataSet1.HTTPFilesInfoRow)
        Do
            If Me.TaskCancelTokenSource.Token.IsCancellationRequested Then
                Exit Do
            End If

            Await Task.Delay(3000)

            Await DownloadFileAsync(Row.T_Link)

            RaiseEvent FileLoaded(Row)
        Loop


        MsgBox("Task Completed...")
    End Sub

    Private Async Function DownloadFileAsync(T_Link As String) As Task(Of Byte())
        Using MyHttpClient As New System.Net.Http.HttpClient()
            Dim GetFileAsync As Task(Of Byte()) = MyHttpClient.GetByteArrayAsync(T_Link)
            Dim FileContents As Byte() = Await GetFileAsync
            Return FileContents
        End Using
    End Function

    Public Sub Cancel()
        Me.TaskCancelTokenSource.Cancel()
        Task.WaitAll(Me.TaskList.ToArray)
        MsgBox("Canceled All")
    End Sub





ليس بالظرورة تعديل الكود المهم مثال ينجح في تطبيق مبداء إنتظار إنتهاء الكل أو إنتظار إلغاء الكل بعدها إستطيع إظهار رسالة تبين أنتهاء الكل أو إلغاء الكل، حتى اتمكن من الإنتقال لمرحلة أخرى بعد التأكد من خروج جميع المهام عن العمل وتوقفها.


أي محاولة ستكون محل تقدير وإمتنان , وشكراً.
وعليكم السلام

أخي عثمان الكود الذي وضعته انت واضح ماذا تريد ، لكن لا يمكن إختبارة لوجود أخطاء ونواقص في الكود , لا يمكن تشغيلة
ضع مثال يمكن إختبارة من قبل الأعضاء, بهذة الطريقة لا احد يستطيع معرف النتيجة التي تحصل عليها انت.
شكراً لك أخي عبدالله
هذة الأكواد قمت بعزلها من المشروع الأساسي
[attachment=28424]

أتمنى أخي عبدالله يكون واضح الكود لأنه متعب جداً إخراج أكواد من مشروع كبير لتعمل بشكل مستقل.

أخواني الأعضاء بارك الله فيكم أحتاج المساعدة