开发多线程应用程序时,经常会有这样的需要:后台线程处理数据,完了在前台界面显示,如:
当DataDealer类数据处理完成后,想在UI中的Msg中输出该怎么办呢?直接访问肯定是不行的
这种情况一般有两种处理方法:
1. Timer
把DataDealer的msg保存到Conf中,UI通过Timer事件定时从Conf中得到数据显示,这方法简单但是缺点显而易见,就是不够时时。
2. 委托+Invoke
要想时时处理,只能DataDealer执行完后触发UI显示数据。
貌似可以这样:
如果是单线程的话,上面的方法确实可行。可是在多线程的情况下,一个线程创建的控件,在另外一个线程中是不能直接访问的。怎么办?只能用Invoke调用,麻烦的是DataDealer不是继承自Form类不能调用Invoke方法,最后只能这样:
看上去很麻烦吧,不过确实能很好的完成工作。
总结一下:
跨线程调用界面控件需要做两步工作:
1.利用委托进入界面线程 2,利用Invoke触发事件
public
class
Conf
{
//用于保存一个多线程共享的数据和全局变量
static string msg;
}
public class UI
{
TextBox Msg;
//界面类
}
public class DataDealer
{
//用来处理数据的线程类
string msg;
}
{
//用于保存一个多线程共享的数据和全局变量
static string msg;
}
public class UI
{
TextBox Msg;
//界面类
}
public class DataDealer
{
//用来处理数据的线程类
string msg;
}
当DataDealer类数据处理完成后,想在UI中的Msg中输出该怎么办呢?直接访问肯定是不行的
这种情况一般有两种处理方法:
1. Timer
把DataDealer的msg保存到Conf中,UI通过Timer事件定时从Conf中得到数据显示,这方法简单但是缺点显而易见,就是不够时时。
2. 委托+Invoke
要想时时处理,只能DataDealer执行完后触发UI显示数据。
貌似可以这样:
public
delegate
void
Message(
string
text);
public class Conf
{
//用于保存一个多线程共享的数据和全局变量
public static Message ShowMessage;
}
public class UI
{
TextBox Msg;
//界面类
UI()
{
Conf.ShowMessage=new Message(ShowText);
}
public ShowText(string msg)
{
Msg.Text=msg;
}
}
public class DataDealer
{
//用来处理数据的线程类
string msg;
public run()
{
Conf.ShowMessge(msg);
}
}
public class Conf
{
//用于保存一个多线程共享的数据和全局变量
public static Message ShowMessage;
}
public class UI
{
TextBox Msg;
//界面类
UI()
{
Conf.ShowMessage=new Message(ShowText);
}
public ShowText(string msg)
{
Msg.Text=msg;
}
}
public class DataDealer
{
//用来处理数据的线程类
string msg;
public run()
{
Conf.ShowMessge(msg);
}
}
如果是单线程的话,上面的方法确实可行。可是在多线程的情况下,一个线程创建的控件,在另外一个线程中是不能直接访问的。怎么办?只能用Invoke调用,麻烦的是DataDealer不是继承自Form类不能调用Invoke方法,最后只能这样:
public
delegate
void
Message(
string
text);
public class Conf
{
//用于保存一个多线程共享的数据和全局变量
public static Message ShowMessage;
}
public class UI
{
TextBox Msg;
Message ShowTxt;
//界面类
UI()
{
Conf.ShowMessage=new Message(GetTxt);
ShowTxt = new Message( ShowText );
}
public ShowText(string msg)
{
Msg.Text=msg;
}
public GetTxt(string msg)
{
Invoke( ShowTxt , msg);
}
}
public class DataDealer
{
//用来处理数据的线程类
string msg;
public run()
{
Conf.ShowMessge(msg);
}
}
public class Conf
{
//用于保存一个多线程共享的数据和全局变量
public static Message ShowMessage;
}
public class UI
{
TextBox Msg;
Message ShowTxt;
//界面类
UI()
{
Conf.ShowMessage=new Message(GetTxt);
ShowTxt = new Message( ShowText );
}
public ShowText(string msg)
{
Msg.Text=msg;
}
public GetTxt(string msg)
{
Invoke( ShowTxt , msg);
}
}
public class DataDealer
{
//用来处理数据的线程类
string msg;
public run()
{
Conf.ShowMessge(msg);
}
}
看上去很麻烦吧,不过确实能很好的完成工作。
总结一下:
跨线程调用界面控件需要做两步工作:
1.利用委托进入界面线程 2,利用Invoke触发事件