admin管理员组文章数量:1025481
I have code that, using UDP, broadcasts the letter "P" to an Arduino WiFi.
It should broadcast 3 times with 3 seconds interval and then stop.
To monitor this, I want to see the broadcast messages sent and the messages returned from the Arduino in a RichTextBox.
As I want to a more complex program, I want to structure it and have therefore put the SendWifiString
method in a class called WifiTools
(which eventually will include a receive method).
I use a System.Timers.Timer
to start the broadcasts, so its Elapsed
event is raised in a ThreadPool Thread. In the Elapsed
event handler, I generate a custom event to then write to the RichTextBox.
I have also added a button to make a broadcast for debugging.
If I test this using "Start Without Debugging" everything works fine, I see the broadcast messages in the RichTextBox, but if I use "Start Debugging" I get a "Cross-thread operation not valid: Control 'richTextBox1' accessed from a thread other than the thread it was created on."
public partial class Form1 : Form
{
System.Timers.Timer broadcastTimer = new System.Timers.Timer();
public int broadcastCounter = 0;
private delegate void RichText(string text);
WifiTools wifiTools = new WifiTools();
public Form1()
{
InitializeComponent();
StartBroadcastTimer(1000);
wifiTools.OnRichText += WifiTools_OnRichText;
}
public class RichTextEventArgs : EventArgs
{
public string? Msg { get; set; }
};
public void WifiTools_OnRichText(object? sender, RichTextEventArgs e)
{
richTextBox1.Text += e.Msg;
}
class WifiTools
{
public event EventHandler<RichTextEventArgs>? OnRichText;
public void SendWifiString(string sendString, string _ipAddress, int port)
{
try
{
UdpClient udpClientSendWifiString = new(_ipAddress, port);
Byte[] sendBytes = Encoding.ASCII.GetBytes(sendString);
udpClientSendWifiString.Send(sendBytes, sendBytes.Length);
string richTextBoxMsg = "\nTX: to " + _ipAddress + ":" + port + " Msg: " + sendString;
OnRichText?.Invoke(null, new RichTextEventArgs { Msg = richTextBoxMsg });
}
catch
{
OnRichText?.Invoke(null, new RichTextEventArgs { Msg = "Wifi Send Fail" });
}
}
};
public void StartBroadcastTimer(int broadcastInterval)
{
broadcastTimer.Interval = broadcastInterval;
broadcastTimer.Start();
broadcastTimer.Elapsed += new System.Timers.ElapsedEventHandler(Broadcast!);
}
private void Broadcast(object sender, EventArgs e)
{
string broadcastAddress = "192.168.1.255";
int remotePort = 23921;
wifiTools.SendWifiString("P", broadcastAddress, remotePort);
broadcastCounter++;
broadcastTimer.Interval = 3000;
if (broadcastCounter > 2)
{
//Stops timer and releases all resources (this timer is only used at program start)
broadcastTimer.Dispose();
broadcastCounter = 0;
}
}
private void buttonBroadcast_Click(object sender, EventArgs e)
{
string broadcastAddress = "192.168.1.255";
int remotePort = 23921;
wifiTools.SendWifiString("P", broadcastAddress, remotePort);
}
}
The exception originates from the catch statement, and occurs in the WifiTools_OnRichText()
method.
If I comment out the code in the catch block:
OnRichText?.Invoke(null, new RichTextEventArgs { Msg = "Wifi Send Fail" });
then debug runs without problem, but noting is written in the RichTextBox. But I can see on my Arduino that the broadcasts were sent.
I have code that, using UDP, broadcasts the letter "P" to an Arduino WiFi.
It should broadcast 3 times with 3 seconds interval and then stop.
To monitor this, I want to see the broadcast messages sent and the messages returned from the Arduino in a RichTextBox.
As I want to a more complex program, I want to structure it and have therefore put the SendWifiString
method in a class called WifiTools
(which eventually will include a receive method).
I use a System.Timers.Timer
to start the broadcasts, so its Elapsed
event is raised in a ThreadPool Thread. In the Elapsed
event handler, I generate a custom event to then write to the RichTextBox.
I have also added a button to make a broadcast for debugging.
If I test this using "Start Without Debugging" everything works fine, I see the broadcast messages in the RichTextBox, but if I use "Start Debugging" I get a "Cross-thread operation not valid: Control 'richTextBox1' accessed from a thread other than the thread it was created on."
public partial class Form1 : Form
{
System.Timers.Timer broadcastTimer = new System.Timers.Timer();
public int broadcastCounter = 0;
private delegate void RichText(string text);
WifiTools wifiTools = new WifiTools();
public Form1()
{
InitializeComponent();
StartBroadcastTimer(1000);
wifiTools.OnRichText += WifiTools_OnRichText;
}
public class RichTextEventArgs : EventArgs
{
public string? Msg { get; set; }
};
public void WifiTools_OnRichText(object? sender, RichTextEventArgs e)
{
richTextBox1.Text += e.Msg;
}
class WifiTools
{
public event EventHandler<RichTextEventArgs>? OnRichText;
public void SendWifiString(string sendString, string _ipAddress, int port)
{
try
{
UdpClient udpClientSendWifiString = new(_ipAddress, port);
Byte[] sendBytes = Encoding.ASCII.GetBytes(sendString);
udpClientSendWifiString.Send(sendBytes, sendBytes.Length);
string richTextBoxMsg = "\nTX: to " + _ipAddress + ":" + port + " Msg: " + sendString;
OnRichText?.Invoke(null, new RichTextEventArgs { Msg = richTextBoxMsg });
}
catch
{
OnRichText?.Invoke(null, new RichTextEventArgs { Msg = "Wifi Send Fail" });
}
}
};
public void StartBroadcastTimer(int broadcastInterval)
{
broadcastTimer.Interval = broadcastInterval;
broadcastTimer.Start();
broadcastTimer.Elapsed += new System.Timers.ElapsedEventHandler(Broadcast!);
}
private void Broadcast(object sender, EventArgs e)
{
string broadcastAddress = "192.168.1.255";
int remotePort = 23921;
wifiTools.SendWifiString("P", broadcastAddress, remotePort);
broadcastCounter++;
broadcastTimer.Interval = 3000;
if (broadcastCounter > 2)
{
//Stops timer and releases all resources (this timer is only used at program start)
broadcastTimer.Dispose();
broadcastCounter = 0;
}
}
private void buttonBroadcast_Click(object sender, EventArgs e)
{
string broadcastAddress = "192.168.1.255";
int remotePort = 23921;
wifiTools.SendWifiString("P", broadcastAddress, remotePort);
}
}
The exception originates from the catch statement, and occurs in the WifiTools_OnRichText()
method.
If I comment out the code in the catch block:
OnRichText?.Invoke(null, new RichTextEventArgs { Msg = "Wifi Send Fail" });
then debug runs without problem, but noting is written in the RichTextBox. But I can see on my Arduino that the broadcasts were sent.
本文标签: cProblem writing to a Control from another class and another threadStack Overflow
版权声明:本文标题:c# - Problem writing to a Control from another class and another thread - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745629105a2160050.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论