旗下导航:搜·么
当前位置:网站首页 > .Net教程 > 正文

从0自学C#02--子线程接见主线程(UI线程)控件【C#.Net教程】,C#,子线程,主线程控件

作者:搜教程发布时间:2019-11-27分类:.Net教程浏览:62评论:0


导读:假如运用多线程处置惩罚来进步Windows窗体应用顺序的机能,则你必需确保以线程平安的体式格局挪用控件。接见Windows窗体控件不是自身就线程平安的。假如有两个或...
假如运用多线程处置惩罚来进步 Windows 窗体应用顺序的机能,则你必需确保以线程平安的体式格局挪用控件。

接见 Windows 窗体控件不是自身就线程平安的。假如有两个或两个以上线程操纵控件的状况,则能够迫使该控件处于不一致状况。能够涌现其他与线程相干的 bug,比方争用前提和死锁。请务必确保以线程平安的体式格局接见控件。

1.初学者经常碰到的题目

从未运用 Invoke 要领建立控件的线程挪用控件是不平安的。下面是一个非线程平安的挪用示例。运转时会激发 InvalidOperationException 音讯,报错“从并未建立该控件的线程接见该控件 控件称号”。

// This event handler creates a thread that calls a // Windows Forms control in an unsafe way.private void setTextUnsafeBtn_Click(    object sender, 
    EventArgs e)
{    this.demoThread = 
        new Thread(new ThreadStart(this.ThreadProcUnsafe));    this.demoThread.Start();
}// This method is executed on the worker thread and makes// an unsafe call on the TextBox control.private void ThreadProcUnsafe()
{    this.textBox1.Text = "This text was set unsafely.";
}


2.解决要领

如需对 Windows 窗体控件举行线程平安的挪用。

①查询控件的 InvokeRequired 属性。

②若 InvokeRequired 返回 true,则用现实挪用控件的托付来挪用 Invoke。

③若 InvokeRequired 返回 false,则请直接挪用控件。

这里分同步实行托付和异步实行托付。

在以下代码示例中,在 ThreadProcSafe 要领中完成了线程平安的挪用,该要领由背景线程实行。若 TextBox 控件的 InvokeRequired 返回 true,则 ThreadProcSafe 要领建立一个 SetTextCallback 实例并将其通报到窗体的 Invoke 要领。这致使在建立了 SetText 控件的线程上挪用 TextBox 要领,并且在该线程高低文中直接设置 Text 属性。

// This event handler creates a thread that calls a 
// Windows Forms control in a thread-safe way.
private void setTextSafeBtn_Click(    
object sender, 
    EventArgs e)
{    this.demoThread = 
        new Thread(new ThreadStart(this.ThreadProcSafe));    
this.demoThread.Start();
}// This method is executed on the worker thread and makes
// a thread-safe call on the TextBox control.
private void ThreadProcSafe()
{    this.SetText("This text was set safely.");
}// This delegate enables asynchronous calls for setting
// the text property on a TextBox control.delegate void SetTextCallback(string text); 
// 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 void SetText(string text)
{    // 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.
    //this.textBox1.InvokeRequired will be replaced by
    //this.InvokeRequired, if want to set many controls' 
    //attribute or text.
    if (this.textBox1.InvokeRequired)// or this.InvokeRequired
    {   
        SetTextCallback d = new SetTextCallback(SetText);        
this.Invoke(d, new object[] { text });
    }    else
    {        this.textBox1.Text = text;
    }
}

3.BackgroundWorker组件

在应用顺序中完成多线程的首选体式格局是运用 BackgroundWorker 组件。 BackgroundWorker 组件为多线程处置惩罚运用事宜驱动模子。背景线程运转你的 DoWork 事宜处置惩罚顺序,建立了你的控件的线程运转 ProgressChanged 和 RunWorkerCompleted 事宜处置惩罚顺序。你能够从 ProgressChanged 和 RunWorkerCompleted 事宜处置惩罚器中挪用控件。

①建立一种要领来举行你想在背景线程中举行的事情。不要挪用由此要领中的主线程所建立的控件。

②建立一种要领来报告背景事情完毕后的背景事情效果。 在此要领中能够挪用主线程建立的控件。

③将步骤 1 中建立的要领绑定到 DoWork 实例中的 BackgroundWorker 事宜,并将步骤 2 中建立的要领绑定到统一实例的 RunWorkerCompleted 事宜。

④若要启动背景线程,请挪用 RunWorkerAsync 实例的 BackgroundWorker 要领。

在以下代码示例中,DoWork 事宜处置惩罚顺序运用 Sleep 来模仿须要消费一些时候的事情。它不会挪用该窗体的 TextBox 控件。TextBox 控件的 Text 属性直接在 RunWorkerCompleted 事宜处置惩罚顺序中设置。

// This BackgroundWorker is used to demonstrate the 
// preferred way of performing asynchronous operations.private BackgroundWorker backgroundWorker1; 
// 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 void setTextBackgroundWorkerBtn_Click(    
object sender, 
    EventArgs e)
{    this.backgroundWorker1.RunWorkerAsync();
}// 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 void backgroundWorker1_RunWorkerCompleted(    
object sender, 
    RunWorkerCompletedEventArgs e)
{    this.textBox1.Text = 
        "This text was set safely by BackgroundWorker.";
}

也可通过运用 ProgressChanged 事宜来报告背景任务的进度。如需包括该事宜的示例,请参阅 BackgroundWorker。

以上就是 从0自学C#02--子线程接见主线程(UI线程)控件的内容,更多相干内容请关注ki4网(www.ki4.cn)!

标签:C#子线程主线程控件


欢迎 发表评论: