C#使用线程还是出现:线程间操作无效: 从不是创建控件“label4”的线程访问它。
程序:publicpartialclassFrm_Main:Form{ThreadthrCli;privatedelegatevoidFlushClient();//代理...
程序:
public partial class Frm_Main : Form
{
Thread thrCli;
private delegate void FlushClient();//代理
public Frm_Main()
{
InitializeComponent();
}
private void Frm_Main_Load(object sender, EventArgs e)
{ thrCli = new Thread(new ThreadStart(connSock));
thrCli.IsBackground = true;
thrCli.Start(); }
public void connSock()
{ FlushClient fc = new FlushClient(ThreadFunction);
fc.BeginInvoke(null, null); }
private void ThreadFunction()
{ while(true)
byte[] retdata = new byte[] { 0x55, 0xAA, 0x04, 0x00, 0x00, 0x00, 0x00, 0x48, 0x10, 0x5C, 0x79, 0x00, 0x00, 0x00, 0x31 };
byte[] shunshibuff = new byte[4];
byte[] liusubuff = new byte[4];
byte[] leijiliangbuff = new byte[4];
shunshibuff[3] = retdata[3];
shunshibuff[2] = retdata[4];
shunshibuff[1] = retdata[5];
shunshibuff[0] = retdata[6];
shun_liuliang = BitConverter.ToSingle(shunshibuff, 0).ToString("0.00");
if (retdata[2] == 01)
{
this.label4.Text = shun_liuliang + "\r\n";
}
Thread.Sleep(1000);
}} 展开
public partial class Frm_Main : Form
{
Thread thrCli;
private delegate void FlushClient();//代理
public Frm_Main()
{
InitializeComponent();
}
private void Frm_Main_Load(object sender, EventArgs e)
{ thrCli = new Thread(new ThreadStart(connSock));
thrCli.IsBackground = true;
thrCli.Start(); }
public void connSock()
{ FlushClient fc = new FlushClient(ThreadFunction);
fc.BeginInvoke(null, null); }
private void ThreadFunction()
{ while(true)
byte[] retdata = new byte[] { 0x55, 0xAA, 0x04, 0x00, 0x00, 0x00, 0x00, 0x48, 0x10, 0x5C, 0x79, 0x00, 0x00, 0x00, 0x31 };
byte[] shunshibuff = new byte[4];
byte[] liusubuff = new byte[4];
byte[] leijiliangbuff = new byte[4];
shunshibuff[3] = retdata[3];
shunshibuff[2] = retdata[4];
shunshibuff[1] = retdata[5];
shunshibuff[0] = retdata[6];
shun_liuliang = BitConverter.ToSingle(shunshibuff, 0).ToString("0.00");
if (retdata[2] == 01)
{
this.label4.Text = shun_liuliang + "\r\n";
}
Thread.Sleep(1000);
}} 展开
2个回答
展开全部
不能从线程里直接使用this.label4.Text = shun_liuliang + "\r\n";这种的东西
因为UI控件操作不是线程安全的
如果要通过线程更改UI,需要使用invoke来做
1.在Form里写一个更改UI的函数
2.声明一个代理,这个代理可以代理这个更改UI的函数
3.函数内部
if(this.label4.invokerequied)//判断是否需要invoke操作
{
//实例化此函数自身的代理
//如果此函数有参数,需要创建一个数组,按参数数量和顺序存放参数
//使用this.label4.begininvoke(代理,参数)来申请UI更新
}
else
{
//更新代码,如this.label4.Text = shun_liuliang + "\r\n";
}
4.线程中,在要更新的地方调用这个函数即可
因为UI控件操作不是线程安全的
如果要通过线程更改UI,需要使用invoke来做
1.在Form里写一个更改UI的函数
2.声明一个代理,这个代理可以代理这个更改UI的函数
3.函数内部
if(this.label4.invokerequied)//判断是否需要invoke操作
{
//实例化此函数自身的代理
//如果此函数有参数,需要创建一个数组,按参数数量和顺序存放参数
//使用this.label4.begininvoke(代理,参数)来申请UI更新
}
else
{
//更新代码,如this.label4.Text = shun_liuliang + "\r\n";
}
4.线程中,在要更新的地方调用这个函数即可
更多追问追答
追问
能不能详细点,更改UI的函数怎么写?
追答
delegate void disp_dg(System.String);
比如你这个我这样写
void dispLabel4(System.String t)
{
if(this.label4.invokerequired)
{
disp_dg s = new disp_dg(dispLabel4);
System.Objet[] p = new System.Object(1);
p[0] = t;
this.label4.begininvoke(s,p);
}
{
this.label4.Text = t;
}
}
展开全部
private static int _i;
private readonly Action<Object> _func;
public Form1()
{
_func = param=>
{
lab.Text = param.ToString();
};
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(TPCount);
}
private void TPCount(object obj)
{
Thread.Sleep(1000);
_i++;
BeginInvoke(_func,_i);
TPCount(obj);
}
给你举一个简单的例子,你在FORM上就放一个Label把Label的name修改成lab,根据简单的来慢慢摸索一下吧
private readonly Action<Object> _func;
public Form1()
{
_func = param=>
{
lab.Text = param.ToString();
};
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(TPCount);
}
private void TPCount(object obj)
{
Thread.Sleep(1000);
_i++;
BeginInvoke(_func,_i);
TPCount(obj);
}
给你举一个简单的例子,你在FORM上就放一个Label把Label的name修改成lab,根据简单的来慢慢摸索一下吧
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询