C#多窗体,多线程编程
我用了委托,FORM2为大厅窗口,其中ListBox显示房间列表,在Form2的窗体类中定义委托实例listboxCallback_f2publicMyInfo.SetL...
我用了委托,FORM2为大厅窗口,其中ListBox显示房间列表,在Form2的窗体类中定义委托实例listboxCallback_f2
public MyInfo .SetListBoxItemCallBack listboxCallback_f2;//其中MyInfo为Form2外的一个类,SetListBoxItemCallBack为类中的静态委托名。
在
public Form2()
{
InitializeComponent();
listboxCallback_f2 = new MyInfo.SetListBoxItemCallBack(MyInfo.SetListBoxItem);
}
在Form2的Load事件中,由于我想在开启大厅的同时,使RoomlistBox随着接受UDP信息而同步刷新,所以我开启了 接受信息并处理RoomListBox的一个线程
Thread RecThread = new Thread(new ThreadStart(MyInfo.MyInfoReceiveAndSetListBoxItem));
//这个MyInfoReceiveAndSetListBoxItem发发也在MyInfo类中
RecThread.Start(ref RoomlistBox ,ref listboxCallback_f2 );
//后边两个是MyInfoReceiveAndSetListBoxItem的参数,我做成了引用
在MyInfo类中我定义了委托,是静态的方法
public delegate void SetListBoxItemCallBack(ListBox listbox,object text,string opreation);
//定义委托
下面是设置listBox方法:
public static void SetListBoxItem(ref SetListBoxItemCallBack listboxCallback,ListBox listbox,object obj,string operation)
//第一个参数我设置成了引用,因为Form2中的委托实例名是 listboxCallback_f2,这个名字是为了便于标记调用委托方法的窗体,其实我的聊天室是多窗体,Form3(房间窗体)也要调用接受UDP方法信息,来更新房间中的成员列表。
//下面是MyInfo类中的 接受信息并处理方法
public static void MyInfoReceiveAndSetListBoxItem(ref ListBox l,ref SetListBoxItemCallBack listboxCallback)
在这个方法中,先接受UDP信息,再要调用和它在同一个类MyInfo中的 SetListBoxItem方法,他们都是静态的
如果当前是Form2调用的,也就是操作Form2中的控件,有:
case "f2": SetListBoxItem(ref listboxCallback,l, MyRoom, SetOrDestroy); break;
//即调用本类中的处理方法
这是我的代码结构,不知您认为合适不合适。
但运行时出了个问题
public MyInfo .SetListBoxItemCallBack listboxCallback_f2;
D:\C#程序\Let's talk!\Form2.cs(20,47): 错误 CS0052: 可访问性不一致: 字段类型“Let_s_talk_.MyInfo.SetListBoxItemCallBack”比字段“Let_s_talk_.Form2.listboxCallback_f2”的可访问性低 展开
public MyInfo .SetListBoxItemCallBack listboxCallback_f2;//其中MyInfo为Form2外的一个类,SetListBoxItemCallBack为类中的静态委托名。
在
public Form2()
{
InitializeComponent();
listboxCallback_f2 = new MyInfo.SetListBoxItemCallBack(MyInfo.SetListBoxItem);
}
在Form2的Load事件中,由于我想在开启大厅的同时,使RoomlistBox随着接受UDP信息而同步刷新,所以我开启了 接受信息并处理RoomListBox的一个线程
Thread RecThread = new Thread(new ThreadStart(MyInfo.MyInfoReceiveAndSetListBoxItem));
//这个MyInfoReceiveAndSetListBoxItem发发也在MyInfo类中
RecThread.Start(ref RoomlistBox ,ref listboxCallback_f2 );
//后边两个是MyInfoReceiveAndSetListBoxItem的参数,我做成了引用
在MyInfo类中我定义了委托,是静态的方法
public delegate void SetListBoxItemCallBack(ListBox listbox,object text,string opreation);
//定义委托
下面是设置listBox方法:
public static void SetListBoxItem(ref SetListBoxItemCallBack listboxCallback,ListBox listbox,object obj,string operation)
//第一个参数我设置成了引用,因为Form2中的委托实例名是 listboxCallback_f2,这个名字是为了便于标记调用委托方法的窗体,其实我的聊天室是多窗体,Form3(房间窗体)也要调用接受UDP方法信息,来更新房间中的成员列表。
//下面是MyInfo类中的 接受信息并处理方法
public static void MyInfoReceiveAndSetListBoxItem(ref ListBox l,ref SetListBoxItemCallBack listboxCallback)
在这个方法中,先接受UDP信息,再要调用和它在同一个类MyInfo中的 SetListBoxItem方法,他们都是静态的
如果当前是Form2调用的,也就是操作Form2中的控件,有:
case "f2": SetListBoxItem(ref listboxCallback,l, MyRoom, SetOrDestroy); break;
//即调用本类中的处理方法
这是我的代码结构,不知您认为合适不合适。
但运行时出了个问题
public MyInfo .SetListBoxItemCallBack listboxCallback_f2;
D:\C#程序\Let's talk!\Form2.cs(20,47): 错误 CS0052: 可访问性不一致: 字段类型“Let_s_talk_.MyInfo.SetListBoxItemCallBack”比字段“Let_s_talk_.Form2.listboxCallback_f2”的可访问性低 展开
2个回答
展开全部
你把委托SetListBoxItemCallBack的定义放到类MyInfo外面就可以了。
另外你用委托来回调SetListBoxItem,是因为担心跨线程访问对象吗?
那你这样做并不合适,可以用.Net的推荐机制:
在MyInfo中定义一个ISynchronizeInvoke对象synchronizingObject:
private ISynchronizeInvoke synchronizingObject;
public MyInfo(ISynchronizeInvoke so)
{
this.synchronizingObject = so;
}
然后根据不同的Form,实例化MyInfo时给他赋值,比如
MyInfo mi = new MyInfo(Form2);
MyInfo mi = new MyInfo(Form3);
这样,你在MyInfo中要更新特定form上的ListBox,只要在this.synchronizingObject上调用Invoke()或者BeginInvoke()就代表了对特定form上的ListBox的操作,不会有跨线程访问的问题了。比如:
if(this.synchronizingObject.InvokeRequired)
{
this.synchronizingObject.BeginInvoke(delegate(){//更新ListBox}, new object[] { // listBox参数 });
}
这时,MyInfoReceiveAndSetListBoxItem(ListBox listBox)虽然在子线程中运行,但它有指向特定Form的synchronizingObject,所以仍然可以安全的更新Form上的ListBox,这个函数也只需要接受一个ListBox参数就行了。
另外你用委托来回调SetListBoxItem,是因为担心跨线程访问对象吗?
那你这样做并不合适,可以用.Net的推荐机制:
在MyInfo中定义一个ISynchronizeInvoke对象synchronizingObject:
private ISynchronizeInvoke synchronizingObject;
public MyInfo(ISynchronizeInvoke so)
{
this.synchronizingObject = so;
}
然后根据不同的Form,实例化MyInfo时给他赋值,比如
MyInfo mi = new MyInfo(Form2);
MyInfo mi = new MyInfo(Form3);
这样,你在MyInfo中要更新特定form上的ListBox,只要在this.synchronizingObject上调用Invoke()或者BeginInvoke()就代表了对特定form上的ListBox的操作,不会有跨线程访问的问题了。比如:
if(this.synchronizingObject.InvokeRequired)
{
this.synchronizingObject.BeginInvoke(delegate(){//更新ListBox}, new object[] { // listBox参数 });
}
这时,MyInfoReceiveAndSetListBoxItem(ListBox listBox)虽然在子线程中运行,但它有指向特定Form的synchronizingObject,所以仍然可以安全的更新Form上的ListBox,这个函数也只需要接受一个ListBox参数就行了。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询