C#接收数据时的委托与事件应用问题求助
Hey there! Let's get your delegate/event setup working to show received data in a UI textbox. I'll walk you through fixing your code and breaking down the key parts you might have missed.
Fixing Your Delegate/Event Setup for UI Data Display
First, here's the adjusted code that properly triggers the event with received data and handles UI updates safely (since you can't modify UI controls directly from a background thread):
// Keep your delegate and event definition as is public delegate void ClientHandleData(byte[] data, int bytesRead); public event ClientHandleData OnDataReceived; // Add these class-level variables if you haven't already private byte[] readBuffer; private const int readBufferSize = 4096; private TcpClient tcpClient; private NetworkStream clientStream; private bool started; private int port; // Assuming you had this defined elsewhere public void ConnectToServer(string ipAddress, int port) { this.port = port; readBuffer = new byte[readBufferSize]; // Initialize your buffer here tcpClient = new TcpClient(ipAddress, port); clientStream = tcpClient.GetStream(); Thread t = new Thread(ListenForData); // Simplified thread syntax started = true; t.Start(); // Subscribe to the event (you can also do this in your UI initialization code) OnDataReceived += HandleReceivedData; } private void ListenForData() { int bytesRead; while (started) { bytesRead = 0; try { bytesRead = clientStream.Read(readBuffer, 0, readBufferSize); } catch (Exception ex) { // Better error handling with details MessageBox.Show($"A socket error has occurred: {ex.Message}"); break; } // Only trigger the event if we actually received data if (bytesRead > 0 && OnDataReceived != null) { // Make a copy of the received bytes (buffer gets overwritten on next read) byte[] receivedData = new byte[bytesRead]; Array.Copy(readBuffer, receivedData, bytesRead); OnDataReceived.Invoke(receivedData, bytesRead); } Thread.Sleep(15); } started = false; Disconnect(); } // This method handles the event and updates the UI safely private void HandleReceivedData(byte[] data, int bytesRead) { // Convert bytes to string - use the encoding your server uses (UTF8 is standard) string receivedText = Encoding.UTF8.GetString(data, 0, bytesRead); // Check if we need to switch to the UI thread (critical for no cross-thread errors) if (yourTextBox.InvokeRequired) { // Use Invoke to run the update on the UI thread yourTextBox.Invoke(new Action(() => { yourTextBox.AppendText(receivedText + Environment.NewLine); })); } else { // Already on the UI thread, update directly yourTextBox.AppendText(receivedText + Environment.NewLine); } } // Don't forget your Disconnect method private void Disconnect() { clientStream?.Close(); tcpClient?.Close(); // Unsubscribe from the event to avoid memory leaks OnDataReceived -= HandleReceivedData; }
Key Fixes & Simple Explanations:
- Actually Triggering the Event: You had the event defined but never called it! Now we copy the received bytes (so we don't pass overwritten buffer data) and invoke
OnDataReceivedwith the valid data. - UI Thread Safety: UI controls can only be touched by the thread they were created on. We check
InvokeRequiredand useInvoketo send the update to the UI thread—this stops those annoying cross-thread exceptions. - String Conversion: We turn the byte array into a readable string using UTF8 encoding. If your server uses a different encoding (like ASCII or UTF16), swap out
Encoding.UTF8for that. - Event Cleanup: We unsubscribe from the event when disconnecting to prevent memory leaks.
- Better Error Handling: The catch block now shows the actual exception message, which makes debugging way easier.
Quick Note for WPF Users:
If you're using WPF instead of WinForms, replace the UI thread check with this:
if (!yourTextBox.Dispatcher.CheckAccess()) { yourTextBox.Dispatcher.Invoke(() => { yourTextBox.AppendText(receivedText + Environment.NewLine); }); } else { yourTextBox.AppendText(receivedText + Environment.NewLine); }
That should get your data showing up in the textbox like you want! If any part feels confusing, just ask.
内容的提问来源于stack exchange,提问作者JamesDrovok5
相关产品推荐
相关产品推荐

