نمایش نتایج 1 تا 15 از 15

نام تاپیک: نحوه استفاده از BackgroundWorker برای همزمان سازی

Hybrid View

پست قبلی پست قبلی   پست بعدی پست بعدی
  1. #1

    نقل قول: نحوه استفاده از BackgroundWorker برای همزمان سازی

    سلام
    يا BackgroundWorker كار مي كردم كه در هنگام اجرا متوجه شدم كه ThreadSafe نيست. دست به دامان MSDN شدم كه راه حل خوبي براش ارائه كرده:


    عنوان مطلب :

    How to: Make Thread-Safe Calls to Windows Forms Controls


    لينك آموزش داخل msdn2005 :

    ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_fxmclictl/html/138f38b6-1099-4fd5-910c-390b41cbad35.htm



    اين هم سورس كد:

    Imports System
    Imports System.ComponentModel
    Imports System.Threading
    Imports System.Windows.Forms

    Public Class form3
    Inherits Form

    ' This delegate enables asynchronous calls for setting
    ' the text property on a TextBox control.
    Delegate Sub SetTextCallback(ByVal [text] As String)

    ' This thread is used to demonstrate both thread-safe and
    ' unsafe ways to call a Windows Forms control.
    Private demoThread As Thread = Nothing

    ' This BackgroundWorker is used to demonstrate the
    ' preferred way of performing asynchronous operations.
    Private WithEvents backgroundWorker1 As BackgroundWorker

    Private textBox1 As TextBox
    Private WithEvents setTextUnsafeBtn As Button
    Private WithEvents setTextSafeBtn As Button
    Private WithEvents setTextBackgroundWorkerBtn As Button

    ' Private components As System.ComponentModel.IContainer = Nothing


    Public Sub New()
    InitializeComponent()
    End Sub


    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    If disposing AndAlso Not (components Is Nothing) Then
    components.Dispose()
    End If
    MyBase.Dispose(disposing)
    End Sub


    ' This event handler creates a thread that calls a
    ' Windows Forms control in an unsafe way.
    Private Sub setTextUnsafeBtn_Click( _
    ByVal sender As Object, _
    ByVal e As EventArgs) Handles setTextUnsafeBtn.Click

    Me.demoThread = New Thread( _
    New ThreadStart(AddressOf Me.ThreadProcUnsafe))

    Me.demoThread.Start()
    End Sub


    ' This method is executed on the worker thread and makes
    ' an unsafe call on the TextBox control.
    Private Sub ThreadProcUnsafe()
    Me.textBox1.Text = "This text was set unsafely."
    End Sub

    ' This event handler creates a thread that calls a
    ' Windows Forms control in a thread-safe way.
    Private Sub setTextSafeBtn_Click( _
    ByVal sender As Object, _
    ByVal e As EventArgs) Handles setTextSafeBtn.Click

    Me.demoThread = New Thread( _
    New ThreadStart(AddressOf Me.ThreadProcSafe))

    Me.demoThread.Start()
    End Sub


    ' This method is executed on the worker thread and makes
    ' a thread-safe call on the TextBox control.
    Private Sub ThreadProcSafe()
    Me.SetText("This text was set safely.")
    End Sub

    ' This method demonstrates a pattern for making thread-safe
    ' calls on a Windows Forms control.
    '
    ' If the calling thread is different from the thread that
    ' created the TextBox control, this method creates a
    ' SetTextCallback and calls itself asynchronously using the
    ' Invoke method.
    '
    ' If the calling thread is the same as the thread that created
    ' the TextBox control, the Text property is set directly.

    Private Sub SetText(ByVal [text] As String)

    ' InvokeRequired required compares the thread ID of the
    ' calling thread to the thread ID of the creating thread.
    ' If these threads are different, it returns true.
    If Me.textBox1.InvokeRequired Then
    Dim d As New SetTextCallback(AddressOf SetText)
    Me.Invoke(d, New Object() {[text]})
    Else
    Me.textBox1.Text = [text]
    End If
    End Sub

    ' This event handler starts the form's
    ' BackgroundWorker by calling RunWorkerAsync.
    '
    ' The Text property of the TextBox control is set
    ' when the BackgroundWorker raises the RunWorkerCompleted
    ' event.
    Private Sub setTextBackgroundWorkerBtn_Click( _
    ByVal sender As Object, _
    ByVal e As EventArgs) Handles setTextBackgroundWorkerBtn.Click
    Me.backgroundWorker1.RunWorkerAsync()
    End Sub


    ' This event handler sets the Text property of the TextBox
    ' control. It is called on the thread that created the
    ' TextBox control, so the call is thread-safe.
    '
    ' BackgroundWorker is the preferred way to perform asynchronous
    ' operations.
    Private Sub backgroundWorker1_RunWorkerCompleted( _
    ByVal sender As Object, _
    ByVal e As RunWorkerCompletedEventArgs) _
    Handles backgroundWorker1.RunWorkerCompleted
    Me.textBox1.Text = _
    "This text was set safely by BackgroundWorker."
    End Sub

    #Region "Windows Form Designer generated code"


    Private Sub InitializeComponent()
    Me.textBox1 = New System.Windows.Forms.TextBox()
    Me.setTextUnsafeBtn = New System.Windows.Forms.Button()
    Me.setTextSafeBtn = New System.Windows.Forms.Button()
    Me.setTextBackgroundWorkerBtn = New System.Windows.Forms.Button()
    Me.backgroundWorker1 = New System.ComponentModel.BackgroundWorker()
    Me.SuspendLayout()
    '
    ' textBox1
    '
    Me.textBox1.Location = New System.Drawing.Point(12, 12)
    Me.textBox1.Name = "textBox1"
    Me.textBox1.Size = New System.Drawing.Size(240, 20)
    Me.textBox1.TabIndex = 0
    '
    ' setTextUnsafeBtn
    '
    Me.setTextUnsafeBtn.Location = New System.Drawing.Point(15, 55)
    Me.setTextUnsafeBtn.Name = "setTextUnsafeBtn"
    Me.setTextUnsafeBtn.TabIndex = 1
    Me.setTextUnsafeBtn.Text = "Unsafe Call"
    '
    ' setTextSafeBtn
    '
    Me.setTextSafeBtn.Location = New System.Drawing.Point(96, 55)
    Me.setTextSafeBtn.Name = "setTextSafeBtn"
    Me.setTextSafeBtn.TabIndex = 2
    Me.setTextSafeBtn.Text = "Safe Call"
    '
    ' setTextBackgroundWorkerBtn
    '
    Me.setTextBackgroundWorkerBtn.Location = New System.Drawing.Point(177, 55)
    Me.setTextBackgroundWorkerBtn.Name = "setTextBackgroundWorkerBtn"
    Me.setTextBackgroundWorkerBtn.TabIndex = 3
    Me.setTextBackgroundWorkerBtn.Text = "Safe BW Call"
    '
    ' backgroundWorker1
    '
    '
    ' form3
    '
    Me.ClientSize = New System.Drawing.Size(268, 96)
    Me.Controls.Add(setTextBackgroundWorkerBtn)
    Me.Controls.Add(setTextSafeBtn)
    Me.Controls.Add(setTextUnsafeBtn)
    Me.Controls.Add(textBox1)
    Me.Name = "form3"
    Me.Text = "form3"
    Me.ResumeLayout(False)
    Me.PerformLayout()
    End Sub 'InitializeComponent

    #End Region

    <STAThread()> _
    Shared Sub Main()
    Application.EnableVisualStyles()
    Application.Run(New form3())
    End Sub
    End Class



  2. #2
    کاربر دائمی آواتار Saeed_m_Farid
    تاریخ عضویت
    تیر 1386
    محل زندگی
    فضای تهی میان دیوارها
    سن
    44
    پست
    1,046

    نقل قول: نحوه استفاده از BackgroundWorker برای همزمان سازی

    نقل قول نوشته شده توسط bashiry مشاهده تاپیک
    سلام
    يا BackgroundWorker كار مي كردم كه در هنگام اجرا متوجه شدم كه ThreadSafe نيست. دست به دامان MSDN شدم كه راه حل خوبي براش ارائه كرده ...
    سلام
    دست شما درد نکنه ولی این که همون لینکی هست که من تو پست اول گذاشتم! شما فقط کد VB اش رو کپی کردید که متاسفانه به درد من نمیخوره ...
    نقل قول نوشته شده توسط Saeed_m_Farid مشاهده تاپیک
    ... تو اینجا یه توضیحاتی در این زمینه داده ولی زیاد با کار من همخوانی نداره ...
    مشکل من از طریق Invoke و Callback حل شد (تو پست سوم همین تاپیک) ولی مشتاقم تا دوستانی که راه حل عملی برای پیاده سازی این کد با BackgroundWorker دارند، ارائه کنند تا نحوه کاربرد اون رو هم یاد بگیریم؛ یعنی من درون تابعی که به Thread معرفی می کنم، بتونم با BackgroundWorker مثلاً دیتاگرید رو Asynchron پر کنم یا addlog رو فراخوانی کنم و ...

    یه چیزی شبیه این، ولی برای کد ذکر شده :

    // This method starts BackgroundWorker by calling
    // RunWorkerAsync. The Text property of the TextBox control
    // is set by a method running in the main thread
    // when BackgroundWorker raises the RunWorkerCompleted event.
    private void setTextBackgroundWorkerBtn_Click(
    object sender,
    EventArgs e)
    {
    this.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
    this.backgroundWorker1.RunWorkerCompleted +=
    new System.ComponentModel.RunWorkerCompletedEventHandl er(this.backgroundWorker1_RunWorkerCompleted);
    this.backgroundWorker1.RunWorkerAsync();

    // Continue in the main thread.
    textBox1.Text = "Written by the main thread.";
    }

    // This method does the work you want done in the background.
    void backgroundWorker1_DoWork (object sender, DoWorkEventArgs e)
    {
    // Wait two seconds to simulate some background work
    // being done.
    Thread.Sleep(2000);

    // You could use the same technique as in the
    // ThreadProcSafe method to set textBox1.Text here, but
    // the preferred method is to do it from the Completed
    // event handler which runs in the same thread as the one
    // that created the control.
    }

    // This method is called by BackgroundWorker's
    // RunWorkerCompleted event. Because it runs in the
    // main thread, it can safely set textBox1.Text.
    private void backgroundWorker1_RunWorkerCompleted(
    object sender,
    RunWorkerCompletedEventArgs e)
    {
    this.textBox1.Text =
    "Written by the main thread after the background thread completed.";
    }


    بازم ممنون.
    آخرین ویرایش به وسیله Saeed_m_Farid : شنبه 12 دی 1388 در 15:16 عصر دلیل: اضافه کردن نقل قول

برچسب های این تاپیک

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •