I"m new to C# and am looking to see if the way I'm using this code to check for a new connection in a background worker is safe and or a better why to do it. My end goal is to run this as a service but, I'm using the background worker as a way to get real-time updates for testing. The code works but I don't know if its safe/stable or the best way to do it?
Any help would be appreciated.
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.RunWorkerAsync(2000);
MessageBox.Show("Started backgroung worker");
}
private void button2_Click(object sender, EventArgs e)
{
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.CancelAsync();
}
MessageBox.Show("Stopped backgroung worker");
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker helperBW = sender as BackgroundWorker;
e.Result = BackgroundProcessLogicMethod(helperBW, arg);
if (helperBW.CancellationPending)
{
e.Cancel = true;
}
}
private int BackgroundProcessLogicMethod(BackgroundWorker bw, int a)
{
while (true)
{
IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] connections = properties.GetActiveTcpConnections();
foreach (TcpConnectionInformation c in connections)
{
if (c.RemoteEndPoint.ToString() == "192.168.4.14:443")
richTextBox1.Invoke(new Action( () => richTextBox1.AppendText(c.RemoteEndPoint.ToString() "\n\r") ) );
}
}
}
CodePudding user response:
Consider throttling the while(true)...
loop but other than that you seem to be doing the right things in your post. This kind of thing shows up a lot in my own production code so I wanted to offer the tried-and-true approach that works for me. It's just another perspective, however.
Your code references RichTextBox
which makes me infer that a WinForms
example will fly here, but the general approach is valid regardless of platform anyway.
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
checkBoxRun.CheckedChanged = onRunChanged;
}
CancellationTokenSource _cts = null;
private async void onRunChanged(object sender, EventArgs e)
{
if (checkBoxRun.Checked)
{
_cts = new CancellationTokenSource();
while (checkBoxRun.Checked)
{
richTextBox1.AppendTextOnUIThread(DateTime.Now.ToString());
IPGlobalProperties properties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] connections = properties.GetActiveTcpConnections();
foreach (TcpConnectionInformation c in connections)
{
var endpoint = c.RemoteEndPoint.ToString();
switch (endpoint)
{
case "192.168.4.14:443":
richTextBox1.AppendTextOnUIThread(endpoint, color: Color.Red);
break;
case "127.0.0.1:49813":
richTextBox1.AppendTextOnUIThread(endpoint, color: Color.Blue);
break;
case "127.0.0.1:55846":
richTextBox1.AppendTextOnUIThread(endpoint, color: Color.Green);
break;
default:
continue;
}
}
richTextBox1.AppendTextOnUIThread();
// Throttle the polling to a reasonable repeat rate.
var task = Task.Delay(TimeSpan.FromSeconds(1), _cts.Token);
try{ await task; } catch (TaskCanceledException){ Debug.WriteLine("Cancelled"); }
}
}
else _cts.Cancel();
}
}
With the following extension for RichTextBox:
static class Extensions
{
public static void AppendTextOnUIThread(this RichTextBox @this, string text = "", bool newLine = true, Color? color = null)
{
if ([email protected])
{
if (newLine) text = $"{text}{Environment.NewLine}";
@this.BeginInvoke(new Action(() =>
{
if (color == null)
{
@this.AppendText(text);
}
else
{
var colorB4 = @this.ForeColor;
@this.SelectionColor = (Color)color;
@this.AppendText(text);
@this.SelectionColor = colorB4;
}
}));
}
}
}