线程间不能相互访问怎么处理
线程间不能相互访问怎么办?
在练习多线程,第一步就被卡到了,希望点击开始按钮开始计时,并每秒刷新一次到Label上,点击停止则停止刷新。
但是从刷新线程无法访问Label,因为Label是在另一个线程创建的。怎么解决?
------解决方案--------------------
使用委托
------解决方案--------------------
label控件是是主线程(UI线程上)上的。
你新开的线程是非UI线程。
非UI线程是不能直接控制UI线程上的控件的。
如果要在非UI线程上去控制UI线程上的控件,只要这样写:
定义一个委托类型,假设
delegate void UpdateHandler(string parameter);
定义更新label的方法,要和委托签名一致
void UpdateLabel(string parameter)
{
窗体.Label.Text = parameter;
}
Thread t =new Thread(()=>{
//你的逻辑...
string parameter=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
//当要切换到UI线程更新时,调用下面的代码
this.Invoke(UpdateLabel,parameter);
});
注意:这里的()=>{...}也是ThreadStart委托的lambda写法。
------解决方案--------------------
ASP.NET里面用多线程确实很少,所以不会也没什么,当然是最好要学会- -。
但是WINFORM里面到处会遇到这种问题,所以必须学会,就楼主的问题,牵涉到委托的lambda写法,线程的基本使用,还要知道一共有4个方法是可以实现安全的跨线程访问线程的,Invoke,BeginInvoke,EndInvoke,CreateGraphics。
在练习多线程,第一步就被卡到了,希望点击开始按钮开始计时,并每秒刷新一次到Label上,点击停止则停止刷新。
但是从刷新线程无法访问Label,因为Label是在另一个线程创建的。怎么解决?
private Thread timeThread;
private DateTime dt;
public void refreshSatus()
{
while (true)
{
runTime_LB.Text = dt.GetDateTimeFormats('t')[0].ToString();
dt.AddSeconds(1);
Thread.Sleep(1);
}
}
private void startButton_Click(object sender, EventArgs e)
{
timeThread = new Thread(new ThreadStart(refreshSatus));
timeThread.Start();
startButton.Enabled = false;
stopButton.Enabled = true;
}
private void stopButton_Click(object sender, EventArgs e)
{
timeThread.Abort();
stopButton.Enabled = false;
stopButton.Enabled = false;
}
------解决方案--------------------
使用委托
while (true)
{
Invoke((MethodInvoker)delegate{ runTime_LB.Text = dt.GetDateTimeFormats('t')[0].ToString();});
dt.AddSeconds(1);
Thread.Sleep(1);
}
------解决方案--------------------
label控件是是主线程(UI线程上)上的。
你新开的线程是非UI线程。
非UI线程是不能直接控制UI线程上的控件的。
如果要在非UI线程上去控制UI线程上的控件,只要这样写:
定义一个委托类型,假设
delegate void UpdateHandler(string parameter);
定义更新label的方法,要和委托签名一致
void UpdateLabel(string parameter)
{
窗体.Label.Text = parameter;
}
Thread t =new Thread(()=>{
//你的逻辑...
string parameter=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
//当要切换到UI线程更新时,调用下面的代码
this.Invoke(UpdateLabel,parameter);
});
注意:这里的()=>{...}也是ThreadStart委托的lambda写法。
------解决方案--------------------
ASP.NET里面用多线程确实很少,所以不会也没什么,当然是最好要学会- -。
但是WINFORM里面到处会遇到这种问题,所以必须学会,就楼主的问题,牵涉到委托的lambda写法,线程的基本使用,还要知道一共有4个方法是可以实现安全的跨线程访问线程的,Invoke,BeginInvoke,EndInvoke,CreateGraphics。