我是 C# 新手,我正在尝试制作一个简单的客户端服务器聊天应用程序。
我的客户端窗口窗体上有 RichTextBox,我正在尝试从另一个类中的服务器更新该控件。当我尝试这样做时,我收到错误:“跨线程操作无效:控制 textBox1 从创建它的线程以外的线程访问”。
这是我的 Windows 窗体的代码:
private Topic topic;
public RichTextBox textbox1;
bool check = topic.addUser(textBoxNickname.Text, ref textbox1, ref listitems);
主题类:
public class Topic : MarshalByRefObject
{
//Some code
public bool addUser(string user, ref RichTextBox textBox1, ref List<string> listBox1)
{
//here i am trying to update that control and where i get that exception
textBox1.Text += "Connected to server... \n";
}
那么如何做到这一点呢?如何从另一个线程更新文本框控件?
我正在尝试使用 .net 远程处理制作一些基本的聊天客户端/服务器应用程序。
我想将 Windows 窗体客户端应用程序和控制台服务器应用程序作为单独的 .exe 文件。在这里,我尝试从客户端调用服务器函数 AddUser,并且我想要 AddUser 函数更新我的 GUI。我已经按照乔恩的建议修改了代码,但现在我得到了这个异常,而不是跨线程异常......“SerializationException:程序集中的类型主题未标记为可序列化”.
我将在下面发布我的整个代码,并尝试使其尽可能简单。
欢迎任何建议。非常感谢。
Server:
namespace Test
{
[Serializable]
public class Topic : MarshalByRefObject
{
public bool AddUser(string user, RichTextBox textBox1, List<string> listBox1)
{
//Send to message only to the client connected
MethodInvoker action = delegate { textBox1.Text += "Connected to server... \n"; };
textBox1.BeginInvoke(action);
//...
return true;
}
public class TheServer
{
public static void Main()
{
int listeningChannel = 1099;
BinaryServerFormatterSinkProvider srvFormatter = new BinaryServerFormatterSinkProvider();
srvFormatter.TypeFilterLevel = TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider clntFormatter = new BinaryClientFormatterSinkProvider();
IDictionary props = new Hashtable();
props["port"] = listeningChannel;
HttpChannel channel = new HttpChannel(props, clntFormatter, srvFormatter);
// Register the channel with the runtime
ChannelServices.RegisterChannel(channel, false);
// Expose the Calculator Object from this Server
RemotingConfiguration.RegisterWellKnownServiceType(typeof(Topic),
"Topic.soap",
WellKnownObjectMode.Singleton);
// Keep the Server running until the user presses enter
Console.WriteLine("The Topic Server is up and running on port {0}", listeningChannel);
Console.WriteLine("Press enter to stop the server...");
Console.ReadLine();
}
}
}
}
Windows 窗体客户端:
// Create and register a channel to communicate to the server
// The Client will use the port passed in as args to listen for callbacks
BinaryServerFormatterSinkProvider srvFormatter = new BinaryServerFormatterSinkProvider();
srvFormatter.TypeFilterLevel = TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider clntFormatter = new BinaryClientFormatterSinkProvider();
IDictionary props = new Hashtable();
props["port"] = 0;
channel = new HttpChannel(props, clntFormatter, srvFormatter);
//channel = new HttpChannel(listeningChannel);
ChannelServices.RegisterChannel(channel, false);
// Create an instance on the remote server and call a method remotely
topic = (Topic)Activator.GetObject(typeof(Topic), // type to create
"http://localhost:1099/Topic.soap" // URI
);
private Topic topic;
public RichTextBox textbox1;
bool check = topic.addUser(textBoxNickname.Text,textBox1, listitems);