【发布时间】:2017-07-31 10:49:04
【问题描述】:
我对多线程相当陌生,因此请原谅可能存在的任何明显错误 - 我还在学习!
我目前有一个程序,它使用TCPClient 和NetworkStream 从端口读取数据并将数据输出到 WPF 程序中的text box。尽管如此,当尝试从stream 多次读取时,它会显着降低程序速度,并且读取的次数越多,程序打开所需的时间就越长。因此我决定尝试实现threading,我正在尝试使用Background Worker。
这是我在MainWindow 中的代码:
InitializeComponent();
try
{
client.Connect(address, port); //connect to the client
nwStream = client.GetStream(); //read in data from stream
readInTxtBox.Text = ("Connection Open");
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync();
}
catch (SocketException ex)
{
readInTxtBox.Text = ex.ToString(); //write out the error
}
finally
{
client.Close();
}
这是worker_DoWork 和worker_RunWorkerCompleted 方法:
void worker_DoWork(object sender, DoWorkEventArgs e)
{
if (Dispatcher.CheckAccess())
{
ReadIn();
}
else
{
Dispatcher.BeginInvoke(new Action(() =>
{
ReadIn();
}));
}
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Dispatcher.BeginInvoke(new Action(() =>
{
OutputToTextBoxInput();
}));
}
当单步执行时,它会转到worker_DoWork 上的Dispatcher.BeginInvoke 操作,并在ReadIn() 方法的第一行失败:
private void ReadIn()
{
byte[] b = Utilities.ReadInBytes(client, nwStream); //fails here!
hex = Utilities.ConvertByteToHex(b);
nwStream.Close();
}
fails在ReadInBytes方法的下面一行,错误:Cannot access a disposed object.
public static byte[] ReadInBytes(TcpClient client, NetworkStream nwStream)
{
byte[] bytesToRead = new byte[client.ReceiveBufferSize]; //FAILS HERE
int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
ArraySegment<byte> segment = new ArraySegment<byte>(bytesToRead, 0, bytesRead);
return segment.ToArray();
}
client 和 network stream 被声明为 public statics。我在使用invoke 时遇到了这个问题,而在没有的时候。我也试过BeginInvoke,也出现了同样的问题。
任何帮助以及对我哪里出错的任何解释都将不胜感激!
【问题讨论】:
-
为什么要发送
ReadIn?如果你想在 GUI 线程上运行它,使用BackgroundWorker... 是没有意义的 ;) -
在 GUI 线程上运行时似乎真的很慢
-
其实我希望上面的代码更慢:P
-
啊,好吧,您认为哪种方法最合适?这个想法是我想循环 ReadIn() 方法以从流中多次读取,因为来自端口的数据是连续的。这就是为什么我觉得有一个与 GUI 不同的线程会更合适,这样它就不会减慢其他进程。
-
因为人们通常会启动很多它们,并且由于这种方法涉及为每个工作人员打开一个新线程,这会导致系统性能问题。人们只是不明白他们在做什么。他们使用的 API 越低,对他们编写的应用程序造成的伤害就越大。
标签: c# wpf multithreading backgroundworker