【发布时间】:2014-04-30 20:31:08
【问题描述】:
我来自嵌入式 C 背景,我正在开发我的第一个 C# 应用程序,但我在这方面遇到了困难,我的研究没有成功,所以我想我会在这里问。
简单的应用程序,到目前为止。我有一个 MainWindow,它在一堆其他东西中,在单击按钮时启动一个 TCPClient 线程:
public partial class MainWindow : Window
{
....
TCPConnection myCon = new TCPConnection();
....
private void connectButton_Click(object sender, RoutedEventArgs e)
{
networkListBox.Items.Add("Connecting...");
myCon.Connect("localhost", updateNetworkListBox);
}
}
....
public void updateNetworkListBox(string message)
{
networkListBox.Items.Add(message);
}
在 TCPConnection.cs 中:
public class TCPConnection
{
....
public void Connect(string server, ReportDelegate reportDelegate)
{
this.server = server;
clientThread = new Thread(() => Client(this.server));
clientThread.Start();
reportDelegate("Started client thread...");
}
static void Client(string server)
{
try
{
Int32 port = 25565;
TcpClient client = new TcpClient(server, port);
Byte[] outgoingBytes = new Byte[1024];
string outgoingString = "Hello! I am " + Guid.NewGuid();
outgoingBytes = System.Text.Encoding.ASCII.GetBytes(outgoingString);
NetworkStream stream = client.GetStream();
stream.Write(outgoingBytes, 0, outgoingBytes.Length);
stream.Close();
client.Close();
}
我想做的第一件事是,既然 TCP 连接正常工作,就是向 UI 发送一条消息,例如“客户端线程正在连接...”、“客户端线程已连接...”并让它显示在网络列表框。
在 Connect() 方法中,我可以通过使用委托来做到这一点,但这显然不适用于新线程,因为无法从另一个线程直接访问 UI 控件。
我已经阅读了大量关于此的文章,并且我知道我可能想使用 Dispatcher 来执行此操作。然而,我看到的几乎所有示例都在当前类中创建了一个新线程,例如,将一个匿名方法传递给 Dispatcher.Invoke()。
this 讨论的一个例外是提倡使用 EventHandler 并在主窗口中对其进行初始化。这似乎不太理想,但也许我错了。
再往下,有人提倡数据共享。同样,这对我来说似乎不太理想。
我读过的其他文章似乎已经过时了。
所以,我欢迎任何有关如何解决此问题的解释。可能是我只是在语法上被挂断了,但我怀疑,虽然我认为我对委托、lambdas 等基本很清楚,但我可能对到底需要完成什么感到困惑。
如果你能在这个具体的例子中通过一些解释来展示它是如何完成的,我将不胜感激。
也许还有一些对我来说有点模糊的具体问题:
1) 我的工作任务可以自行访问还是必须通过 UI 的 Dispatcher 提供?
2) UI 是否应该提供一个执行调度的委托,或者调度是否应该在工作任务中编码,引用 UI 调度程序?
非常感谢。
【问题讨论】:
-
只是关于风格的说明。使用实现 IDisposable 的对象时,通常最好将其包装在“使用”语句中。 TcpClient 和 NetworkStream 都实现了 IDisposable。这是link 解释“使用”语句。用 C# 玩得开心!
标签: c# wpf multithreading user-interface dispatcher