C# 如何从c中的不同线程构造新的WPF表单#
我对线程的概念以及如何使用线程有困难 我正在尝试编写一个相当基本的聊天程序(作为更大程序的一部分),它目前的工作方式如下: “NetworkSession”类在循环中的一个单独线程上接收来自服务器的输入。如果它收到指示它应该打开一个新的聊天窗口的输入,它将构造一个新的WPF类(聊天窗口)并显示它 最初我得到的错误是“调用线程必须是STA,因为许多UI组件都需要它。”。所以我将线程设置为STA,但现在WPF表单当然不可用,因为它与阻塞循环运行在同一线程上 所以我的问题是如何从另一个线程中创建WPF表单的新实例 我已经看到了很多关于这方面的讨论,但它倾向于处理从已经构建的表单运行委托的问题 下面是一些代码C# 如何从c中的不同线程构造新的WPF表单#,c#,wpf,multithreading,C#,Wpf,Multithreading,我对线程的概念以及如何使用线程有困难 我正在尝试编写一个相当基本的聊天程序(作为更大程序的一部分),它目前的工作方式如下: “NetworkSession”类在循环中的一个单独线程上接收来自服务器的输入。如果它收到指示它应该打开一个新的聊天窗口的输入,它将构造一个新的WPF类(聊天窗口)并显示它 最初我得到的错误是“调用线程必须是STA,因为许多UI组件都需要它。”。所以我将线程设置为STA,但现在WPF表单当然不可用,因为它与阻塞循环运行在同一线程上 所以我的问题是如何从另一个线程中创建WPF
while (Connected) //this loop is running on its own thread
{
Resp = srReceiver.ReadLine();
if (Resp.StartsWith("PING")) SendToServer("PONG");
if (Resp.StartsWith("CHAT FROM"))
{
String[] split = Resp.Split(' ');
Console.WriteLine("Incoming Chat from {0}", split[2]);
bool found = false;
if (Chats.Count != 0)
{
foreach (ChatWindow cw in Chats)
{
if (cw.User == split[2])
{
found = true;
cw.AddLine(cw.User, split[3]); // a function that adds a line to the current chat
}
}
}
if (!found)
{
ChatWindow temp = new ChatWindow(split[2], split[3]);
Chats.Add(temp); //this is a collection with T = ChatWindow
temp.Show();
}
}
}
您真正需要做的是在主UI线程上构造窗口/表单。您可能需要定义一个可以从网络线程调用的委托,并且该委托应该附加一个方法来调用此.Dispatcher.BeginInvoke()->,您将在其中构造窗口 this.Dispatcher.BeginInvoke()调用是在UI线程上执行代码所必需的,否则即使使用委托,代码也会在网络线程上执行
委托和创建新聊天窗口的方法可能都应该附加到主窗口…如果您正在从UI线程构建NetworkSession,您可以找到对当前
调度程序的引用,该调度程序可在以后操作UI
NetworkSession.cs
private Dispatcher _dispatcher;
public NetworkSession()
{
_dispatcher = Dispatcher.CurrentDispatcher;
}
//any thread can call this method
public void DoStuff()
{
Action action = () =>
{
ChatWindow temp = new ChatWindow(split[2], split[3]);
Chats.Add(temp);
temp.Show();
};
_dispatcher.BeginInvoke(action);
}
下面的代码是我从中提取的,为我工作:
public static void StartChatWindow()
{
Thread thread = new Thread(() =>
{
ChatWindow chatWindow = new ChatWindow();
chatWindow.Chat(); // Do your stuff here, may pass some parameters
chatWindow.Closed += (sender2, e2) =>
// Close the message pump when the window closed
chatWindow.Dispatcher.InvokeShutdown();
// Run the message pump
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}