سؤال

في قانون بلدي، وعندما يتم النقر على زر تعيين شريط التقدم إلى سرادق ومن ثم دعا لي 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 للسماح للخروج كود الاستدعاء. منذ هذا لا يسمح القانون الأساسي لمتابعة تشغيل كنت قد وضعت الدعوة في الدعوة الخلفية أو موضوع آخر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top