سرادق ProgressBar لا تستجيب مع BackgroundWorker
-
06-07-2019 - |
سؤال
في قانون بلدي، وعندما يتم النقر على زر تعيين شريط التقدم إلى سرادق ومن ثم دعا لي BackgroundWorker لكن عندما يتم استدعاء BackgroundWorker يتجمد شريط التقدم أو يختفي. يمكنني استخدام BackgroundWorker للتفريق بين طريقة RefreshReport من ReportViewer من موضوع UI. ويقدر أي مساعدة. شكرا!
Private Sub btnOtherReport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOtherReport.Click
rvReport.ProcessingMode = ProcessingMode.Remote
rvReport.ShowParameterPrompts = False
rvReport.ServerReport.ReportServerUrl = New Uri("REPORT_SERVER_URL")
rvReport.ServerReport.ReportPath = "REPORT_PATH"
rvReport.BackColor = Color.White
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
RefreshReport()
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
pbReports.Style = ProgressBarStyle.Blocks
pbReports.Value = 100
End Sub
Public Sub RefreshReport()
rvReport.BeginInvoke(New MethodInvoker(AddressOf rvReport.RefreshReport))
End Sub
المحلول
والمشكلة هي عند استدعاء .BeginInvoke()
في طريقة RefreshReport()
الخاص بك. وأثارت طريقة BackgroundWorker.DoWork()
بالفعل في موضوع مختلف، لذلك يمكنك الاتصال فقط rvReport.RefreshReport()
. ينبغي أن تبدو هذه:
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
rvReport.RefreshReport()
End Sub
وانها حقا بهذه البساطة، مع إمكانية إضافة باستخدام Monitor
لقفل الكائن التقرير الخاص بك ومنع إعادة الدخول.
والآن، عند استدعاء .BeginInvoke()
عملية تقرير تنطلق، لكنه لا يمنع على الإطلاق حيث لا يوجد شيء ترك للأسلوب DoWork()
القيام به. فإنها ترجع فقط على الفور. عند هذه النقطة BackgroundWorker يعتقد انها فعلت، لذلك يستدعي الأسلوب .RunWorkerCompleted()
، الذي يتوقف شريط التقدم المحرز الخاص بك.
واستنادا إلى التعليق، rvReport
هو المراقبة البصرية بدلا من مكون أو بسيطة الطبقة الوصول إلى البيانات. في هذه الحالة، يجب أن نعرف أن الضوابط البصرية في صافي لا الخيط آمنة، وبالتالي يجب أن <م> لا م> القيام مباشرة أي شيء مباشرة التي تأخذ أكثر من بضع لحظات لإكمال. كان الأطواق كنت القفز من خلال مع .BeginInvoke()
في طريقة RefreshReport()
تأثير دعوتكم وظيفة تشغيل طويلة <م> في موضوع UI الرئيسي م>.
ولحل هذه المشكلة، تحتاج إلى إما إيقاف عبر فحص موضوع بحيث لا يتم طرح استثناء (بسيطة، ولكن لا ينصح به) أو تغيير كيفية استخدام جهاز التحكم، بحيث يحدث العمل الرئيسي في أماكن أخرى والسيطرة فقط يثير الأحداث عندما تكون الأمور جاهزة. إذا كنت لا يمكن تعديل عنصر التحكم إلى هذا الحد، انها عيب تصميم في السيطرة عليها.
نصائح أخرى
والمشكلة هي أن شريط التقدم لا يتم إعطاء فرصة لإعادة رسم بينما THEAD الخلفية لديه المعالج. لذلك تحتاج إلى استدعاء System.Windows.Forms.Application.DoEvents () من موضوع الانتظار الرئيسي بينما كنت معالجة. هذا وسوف تحصل السيطرة وتتسبب في شريط التقدم لإعادة رسم.
وحتى بعد BackgroundWorker1.RunWorkerAsync استدعاء يمكنك إضافة حلقة لاستدعاء الدالة DoEvents حتى يتم رفع هذا الحدث ومن ثم رفع الحدث في RunWorkerCompleted للسماح للخروج كود الاستدعاء. منذ هذا لا يسمح القانون الأساسي لمتابعة تشغيل كنت قد وضعت الدعوة في الدعوة الخلفية أو موضوع آخر.