03-11-22, 01:47 PM
السلام عليكم ورحمة الله وبركاتة
تحياتي لل الأعضاء الكرام
بعد محاولات كثيرة لم أستطع أو أستوعب ما هو المطلوب لكي أتمكن من إنتظار عدة مهام ( 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 )
ليس بالظرورة تعديل الكود المهم مثال ينجح في تطبيق مبداء إنتظار إنتهاء الكل أو إنتظار إلغاء الكل بعدها إستطيع إظهار رسالة تبين أنتهاء الكل أو إلغاء الكل، حتى اتمكن من الإنتقال لمرحلة أخرى بعد التأكد من خروج جميع المهام عن العمل وتوقفها.
أي محاولة ستكون محل تقدير وإمتنان , وشكراً.
تحياتي لل الأعضاء الكرام
بعد محاولات كثيرة لم أستطع أو أستوعب ما هو المطلوب لكي أتمكن من إنتظار عدة مهام ( 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
ليس بالظرورة تعديل الكود المهم مثال ينجح في تطبيق مبداء إنتظار إنتهاء الكل أو إنتظار إلغاء الكل بعدها إستطيع إظهار رسالة تبين أنتهاء الكل أو إلغاء الكل، حتى اتمكن من الإنتقال لمرحلة أخرى بعد التأكد من خروج جميع المهام عن العمل وتوقفها.
أي محاولة ستكون محل تقدير وإمتنان , وشكراً.