C# WPF Ping Exception - c#

I have this code working as is but no matter what I try, if you enter an invalid address I get a PingException and the program crashes. What is the best way to capture the exception and just update the textblock to "Device not found"?
private void actionPing_Click(object sender, RoutedEventArgs e)
{
Ping myPing = new Ping();
PingReply reply = myPing.Send(HostNameTyped.Text.ToString(), 1000);
if (reply != null)
{
string tripTime = reply.RoundtripTime.ToString();
if (tripTime == "0")
{
PingStatus1.Text = "Device not found";
}
else
{
PingStatus1.Text = "Ping Successful, " + reply.RoundtripTime.ToString() + "ms roundtrip";
}
}

https://learn.microsoft.com/en-sg/dotnet/csharp/language-reference/keywords/try-catch
try
{
Ping myPing = new Ping();
PingReply reply = myPing.Send(HostNameTyped.Text.ToString(), 1000);
if (reply != null)
{
string tripTime = reply.RoundtripTime.ToString();
if (tripTime == "0")
{
PingStatus1.Text = "Device not found";
}
else
{
PingStatus1.Text = "Ping Successful, " + reply.RoundtripTime.ToString() + "ms roundtrip";
}
}
}
catch
{
PingStatus1.Text = "Device not found";
}

Related

How to more efficiently set properties of multiple Form Controls

My problem is that I have multiple Forms Controls that I need to make visible/invisible/change text, based on the output of my code.
Obviously this is very easy to achieve but the code is ridiculously long due to how I've set it up.
I have 3 image boxes containing a red, green and orange 'light'.
When the ping action is started (button click or a timer) all the controls need to be set like so:
// ping 1
redLight1.Visible = true;
greenLight1.Visible = false;
orangeLight1.Visible = false;
status_Lbl1.Text = "Initiated...";
I need to do this 9 times, and the code looks a bit meh to me having this repeated this many times.
I have a ping object that sends a ping every second for x amount of time. If all of the pings are sent and received successfully then an imagebox containing a green circle becomes visible greenLight1.Visible = true, while all others are set redLight1.Visible = false, orangeLight1.Visible = false, etc.
I have 9 of these sets of 'traffic lights', with a different IP being pinged and a different outcome for each.
I feel there must be a way to iteratively change the values of each of these boxes using the fact they all follow the same naming convention with just a different number on the end corresponding to the ping object they represent.
Here's a more visual idea of what I want to achieve.
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// int counter = 0
if (e.Cancelled == true)
{
status_Lbl1.Text = "Cancelled";
}
else if (e.Error != null)
{
status_Lbl1.Text = "Error: " + e.Error.Message;
}
else
{
foreach (Ping pingObj in pings)
{
if (pingObj.SuccessfulPings == 0)
{
Debug.WriteLine("Ping Object: " + pingObj.Fqdn + " failed to successfully ping");
// greenLight[i].Visible = false;
// orangeLight[i].Visible = false;
// redLight[i].Visible = true;
// counter++
}
else if (pingObj.FailedPings != 0)
{
Debug.WriteLine("Ping Object: " + pingObj.Fqdn + " failed to successfully ping: " + pingObj.FailedPings + " times.");
// greenLight[i].Visible = false;
// orangeLight[i].Visible = true;
// redLight[i].Visible = false;
// counter++
}
else
{
Debug.WriteLine("Ping Object: " + pingObj.Fqdn + " succesfully pinged: " + pingObj.SuccessfulPings + " times.");
// greenLight[i].Visible = false;
// orangeLight[i].Visible = false;
// redLight[i].Visible = false;
// counter++
}
}
}
}
Here's the method that creates/uses the ping objects just in case that is necessary
private async void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
// Create background worker
BackgroundWorker worker = (BackgroundWorker)sender;
// Write to log file
await file.WriteAsync("Starting job...\n");
await file.WriteAsync("Requested amount of pings: " + count + "\n");
// Create date object for logs
DateTime localDate = DateTime.Now;
for (int i = 0; i < count; i++)
{
// Create ping objects
System.Net.NetworkInformation.Ping pinger = new System.Net.NetworkInformation.Ping();
PingReply pingReply;
try
{
foreach (Ping pingObj in pings)
{
try
{
pingReply = pinger.Send(pingObj.IpAddress);
// Write log file
await file.WriteLineAsync(localDate.TimeOfDay + " | Friendly Name " + pingObj.FriendlyName + " | Ping: " + pingReply.Address + " | Status " + pingReply.Status + " | Time: " + pingReply.RoundtripTime);
if (pingReply.Status.ToString().Contains("Success"))
{
pingObj.SuccessfulPings += 1;
}
else // Unsuccessful ping has been sent
{
pingObj.FailedPings += 1;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
wait(1000);
}
catch (Exception b)
{
Debug.WriteLine(b.ToString());
}
}
}
catch (Exception a)
{
Debug.WriteLine(a.ToString());
}
}
You can use Controls.Find() and "search by name" with the recurse option:
Control ctl = this.Controls.Find("greenLight" + counter, true).FirstOrDefault() as Control;
if (ctl != null) {
ctl.Visible = false;
}

Multithread using backgroundworker and event handler

I'm developing a sample program to connect multiple device using backgroundworker. Each device connected will be add to the list as new object. After finished connecting all the devices, i wanted to add an event handler for each connected devices. The problem that i'm facing now is the event handler doesn't firing at all. Below are the sample codes.
The Connect click button event :
private void btnConnect_Click(object sender, EventArgs e)
{
using (BackgroundWorker m_oWorker = new BackgroundWorker())
{
m_oWorker.DoWork += delegate (object s, DoWorkEventArgs args)
{
int iIpStart = 0;
int iIpEnd = 0;
string strIp1 = string.Empty;
string strIp2 = string.Empty;
list.Clear();
string[] sIP1 = txtIpStart.Text.Trim().ToString().Split('.');
string[] sIP2 = txtIpEnd.Text.Trim().ToString().Split('.');
iIpStart = Convert.ToInt32(sIP1[3]);
iIpEnd = Convert.ToInt32(sIP2[3]);
strIp1 = sIP1[0] + "." + sIP1[1] + "." + sIP1[2] + ".";
strIp2 = sIP2[0] + "." + sIP2[1] + "." + sIP2[2] + ".";
Ping ping = new Ping();
PingReply reply = null;
int iIncre = 0;
int iVal = (100 / (iIpEnd - iIpStart));
for (int i = iIpStart; i <= iIpEnd; i++)
{
Thread.Sleep(100);
string strIpconnect = strIp1 + i.ToString();
Console.Write("ip address : " + strIpconnect + ", status: ");
reply = ping.Send(strIpconnect);
if (reply.Status.ToString() == "Success")
{
if (ConnectDevice(strIpconnect))
{
strLastDevice = strIpconnect + " Connected";
isconnected = true;
}
else
{
isconnected = false;
}
}
else
{
isconnected = false;
}
m_oWorker.ReportProgress(iIncre);
iIncre = iIncre + iVal;
}
m_oWorker.ReportProgress(100);
};
m_oWorker.ProgressChanged += new ProgressChangedEventHandler(m_oWorker_ProgressChanged);
m_oWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_oWorker_RunWorkerCompleted);
m_oWorker.WorkerReportsProgress = true;
m_oWorker.WorkerSupportsCancellation = true;
m_oWorker.RunWorkerAsync();
}
}
ConnectDevice function method. Connected device will be added to the list :
protected bool ConnectDevice(string sIP)
{
try
{
NewSDK sdk = new NewSDK();
if (sdk.Connect() == true)
{
list.Add(new objSDK { sdk = sdk, ipaddress = sIP });
return true;
}
else
{
}
}
catch() {}
return false;
}
the Backgroundworker :
void m_oWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//If it was cancelled midway
if (e.Cancelled)
{
lblStatus.Text = "Task Cancelled.";
}
else if (e.Error != null)
{
lblStatus.Text = "Error while performing background operation.";
}
else
{
lblStatus.Text = "Task Completed...";
btnListen.Enabled = true;
}
}
void m_oWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//Here you play with the main UI thread
progressBar1.Value = e.ProgressPercentage;
lblStatus.Text = "Processing......" + progressBar1.Value.ToString() + "%";
if (isconnected)
{
listBox2.Items.Add(strLastDevice);
string[] ssplit = sDeviceInfo.Split(';');
foreach (string sword in ssplit)
{
listBox1.Items.Add(sword);
}
}
}
The function to attached event :
private void RegisterEvent()
{
foreach (objSDK obj in list)
{
obj.sdk.OnTransaction += () =>
{
listBox1.Items.Add("ip : " + obj.IP + " transaction");
};
}
}
You have declared m_oWorker as a local variable. I'm guessing this was a mistake ( the m_ prefix should only be used for class member variables)?
Also, you declared it within a using statement, meaning that it that the framework will call Dispose() on it at the end of the using block. Even if you held on to a reference to it (and I don't think you do) it still means its resources will be deallocated, which is probably why it isn't handling any events.
I try another workaround by using thread and task and work perfectly. Thanks for all response

send message from my web page (client) to a pc (server)?

i would like to send message from my web page (client) to a pc
Problem comes in when I try to send data. It complains about this line: m_socWorker.Send(byData); Error Message is Object reference not set to an instance of an object.
here is my code
// Counts the pings
private int pingsSent;
// Can be used to notify when the operation completes
AutoResetEvent resetEvent = new AutoResetEvent(false);
public static Socket m_socWorker;
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
if (DropDownList2.SelectedIndex != null)
{
// Reset the number of pings
pingsSent = 0;
// Clear the textbox of any previous content
TextBox2.Dispose();
TextBox2.Text += "Pinging " + DropDownList1.SelectedValue + " with 32 bytes of data:\r\n\r\n";
// Send the ping
Thread thd = new Thread(new ThreadStart(SendPing));
thd.Start();
//SendPing();
try
{
UdpClient udpclient = new UdpClient();
IPAddress remotipadd = IPAddress.Parse(DropDownList1.SelectedValue);
udpclient.Connect(remotipadd,10001);
byte[] data = new byte[1024];
IPEndPoint senderip = new IPEndPoint(remotipadd, Convert.ToInt32(DropDownList2.SelectedValue));
udpclient.Connect(senderip);
TextBox2.Text += "Connect";
// listbox1.Items.Add("connected");
}
catch (SocketException s)
{
MessageBox.Show(s.Message);
}
}
}
private void SendPing()
{
System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
// Create an event handler for ping complete
pingSender.PingCompleted += new PingCompletedEventHandler(pingSender_Complete);
// Create a buffer of 32 bytes of data to be transmitted.
byte[] packetData = Encoding.ASCII.GetBytes("................................");
// Jump though 50 routing nodes tops, and don't fragment the packet
PingOptions packetOptions = new PingOptions(50, true);
// Send the ping asynchronously
pingSender.SendAsync(DropDownList1.SelectedValue, 5000, packetData, packetOptions, resetEvent);
}
private void pingSender_Complete(object sender, PingCompletedEventArgs e)
{
// If the operation was canceled, display a message to the user.
if (e.Cancelled)
{
TextBox2.Text += "Ping was canceled...\r\n";
// The main thread can resume
((AutoResetEvent)e.UserState).Set();
}
else if (e.Error != null)
{
TextBox2.Text += "An error occured: " + e.Error + "\r\n";
// The main thread can resume
((AutoResetEvent)e.UserState).Set();
}
else
{
PingReply pingResponse = e.Reply;
// Call the method that displays the ping results, and pass the information with it
ShowPingResults(pingResponse);
}
}
public void ShowPingResults(PingReply pingResponse)
{
if (pingResponse == null)
{
// We got no response
TextBox2.Text += "There was no response.\r\n\r\n";
return;
}
else if (pingResponse.Status == IPStatus.Success)
{
// We got a response, let's see the statistics
TextBox2.Text += "Reply from " + pingResponse.Address.ToString() + ": bytes=" + pingResponse.Buffer.Length + " time=" + pingResponse.RoundtripTime + " TTL=" + pingResponse.Options.Ttl + "\r\n";
}
else
{
// The packet didn't get back as expected, explain why
TextBox2.Text += "Ping was unsuccessful: " + pingResponse.Status + "\r\n\r\n";
}
// Increase the counter so that we can keep track of the pings sent
pingsSent++;
// Send 4 pings
if (pingsSent < 4)
{
SendPing();
}
}
protected void Button2_Click(object sender, EventArgs e)
{
try
{
Object objData = TextBox2.Text;
byte[] byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString());
//Session["m_socWorker"] = m_socWorker;
//m_socWorker = (Socket) Session["m_socWorker"];
m_socWorker.Send(byData);
}
catch (SocketException se)
{
MessageBox.Show(se.Message);
}
}

App Crashes Every Time on an unsuccessfull ping C#

I was developing my first app called Minecraft Wiglet. It pings important minecraft sites and it can start in starup. When I am testing my app it succesfully pinged sites while
I was online but when I was offline the app crashed at the fourth line it said "unhandled pingExpection" I am new in coding so go easy on me :)
private void button1_Click(object sender, EventArgs e)
{
Ping ping = new Ping();
PingReply pingresult = ping.Send("minecraftturk.com"); //Crashed here
if (pingresult.Status.ToString() == "Success")
{
label5.Text = "Online";
}
else if (pingresult.Status.ToString() == "Failure")
{
label5.Text = "Offline";
}
Ping ping1 = new Ping();
PingReply pingresult1 = ping.Send("minecraft.net");
if (pingresult.Status.ToString() == "Success")
{
label3.Text = "Online";
}
else if (pingresult.Status.ToString() == "Failure")
{
label3.Text = "Offline";
}
Ping ping2 = new Ping();
PingReply pingresult2 = ping.Send("www.planetminecraft.com");
if (pingresult.Status.ToString() == "Success")
{
label10.Text = "Online";
}
else if (pingresult.Status.ToString() == "Failure")
{
label10.Text = "Offline";
}
MessageBox.Show("Durum başarıyla güncellendi.");
}
You need to catch and handle your exceptions. I'd recommend wrapping your pinging into another method like this:
private bool CanPing(string url)
{
try
{
return new Ping().Send(url).Status == IPStatus.Success;
}
catch (PingException)
{
return false;
}
}
Then you can call CanPing for each site and it will return true or false while handling the case where the user is offline in just one line, like so:
private void button1_Click(object sender, EventArgs e)
{
label10.Text = CanPing("www.planetminecraft.com") ? "Online" : "Offline";
// ...
}
You could further encapsulate the above into another method, but that might be overkill.

Need to send email using background worker process

I have code written for sending email in C#, but the application hangs up when the application is sending mails size of attachments more than 2 MB. I was advised to use background worker process for the same by SO users.
I have gone thru the background worker process example from MSDN and google it also, but i don't know how to integrate in my code.
Please guide me in that...
thanks
UPDATED: Email-Code Added
public static void SendMail(string fromAddress, string[] toAddress, string[] ccAddress, string[] bccAddress, string subject, string messageBody, bool isBodyHtml, ArrayList attachments, string host, string username, string pwd, string port)
{
Int32 TimeoutValue = 0;
Int32 FileAttachmentLength = 0;
{
try
{
if (isBodyHtml && !htmlTaxExpression.IsMatch(messageBody))
isBodyHtml = false;
// Create the mail message
MailMessage objMailMsg;
objMailMsg = new MailMessage();
if (toAddress != null) {
foreach (string toAddr in toAddress)
objMailMsg.To.Add(new MailAddress(toAddr));
}
if (ccAddress != null) {
foreach (string ccAddr in ccAddress)
objMailMsg.CC.Add(new MailAddress(ccAddr));
}
if (bccAddress != null) {
foreach (string bccAddr in bccAddress)
objMailMsg.Bcc.Add(new MailAddress(bccAddr));
}
if (fromAddress != null && fromAddress.Trim().Length > 0) {
//if (fromAddress != null && fromName.trim().length > 0)
// objMailMsg.From = new MailAddress(fromAddress, fromName);
//else
objMailMsg.From = new MailAddress(fromAddress);
}
objMailMsg.BodyEncoding = Encoding.UTF8;
objMailMsg.Subject = subject;
objMailMsg.Body = messageBody;
objMailMsg.IsBodyHtml = isBodyHtml;
if (attachments != null) {
foreach (string fileName in attachments) {
if (fileName.Trim().Length > 0 && File.Exists(fileName)) {
Attachment objAttachment = new Attachment(fileName);
FileAttachmentLength=Convert.ToInt32(objAttachment.ContentStream.Length);
if (FileAttachmentLength >= 2097152) {
TimeoutValue = 900000;
} else {
TimeoutValue = 300000;
}
objMailMsg.Attachments.Add(objAttachment);
//objMailMsg.Attachments.Add(new Attachment(fileName));
}
}
}
//prepare to send mail via SMTP transport
SmtpClient objSMTPClient = new SmtpClient();
if (objSMTPClient.Credentials != null) { } else {
objSMTPClient.UseDefaultCredentials = false;
NetworkCredential SMTPUserInfo = new NetworkCredential(username, pwd);
objSMTPClient.Host = host;
objSMTPClient.Port = Int16.Parse(port);
//objSMTPClient.UseDefaultCredentials = false;
objSMTPClient.Credentials = SMTPUserInfo;
//objSMTPClient.EnableSsl = true;
//objSMTPClient.DeliveryMethod = SmtpDeliveryMethod.Network;
}
//objSMTPClient.Host = stmpservername;
//objSMTPClient.Credentials
//System.Net.Configuration.MailSettingsSectionGroup mMailsettings = null;
//string mailHost = mMailsettings.Smtp.Network.Host;
try {
objSMTPClient.Timeout = TimeoutValue;
objSMTPClient.Send(objMailMsg);
//objSMTPClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
objMailMsg.Dispose();
}
catch (SmtpException smtpEx) {
if (smtpEx.Message.Contains("secure connection")) {
objSMTPClient.EnableSsl = true;
objSMTPClient.Send(objMailMsg);
}
}
}
catch (Exception ex)
{
AppError objError = new AppError(AppErrorType.ERR_SENDING_MAIL, null, null, new AppSession(), ex);
objError.PostError();
throw ex;
}
}
}
I can't modify the code here as it is common method that is called whenever mail is to be sent from my application.
You could start a background thread to continuously loop and send email:
private void buttonStart_Click(object sender, EventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
this.Controls.Add(bw);
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync();
}
private bool quit = false;
void bw_DoWork(object sender, DoWorkEventArgs e)
{
while (!quit)
{
// Code to send email here
}
}
Alternative way to do it:
private void buttonStart_Click(object sender, EventArgs e)
{
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
client.SendCompleted += new System.Net.Mail.SendCompletedEventHandler(client_SendCompleted);
client.SendAsync("from#here.com", "to#there.com", "subject", "body", null);
}
void client_SendCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error == null)
MessageBox.Show("Successful");
else
MessageBox.Show("Error: " + e.Error.ToString());
}
Specific to your example, you should replace the following:
try
{
objSMTPClient.Timeout = TimeoutValue;
objSMTPClient.Send(objMailMsg);
//objSMTPClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
objMailMsg.Dispose();
}
catch (SmtpException smtpEx)
{
if (smtpEx.Message.Contains("secure connection"))
{
objSMTPClient.EnableSsl = true;
objSMTPClient.Send(objMailMsg);
}
}
with the following:
objSMTPClient.Timeout = TimeoutValue;
objSMTPClient.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);
objSMTPClient.SendAsync(objMailMsg, objSMTPClient);
and further down, include:
void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
if (e.Error == null)
MessageBox.Show("Successful");
else if (e.Error is SmtpException)
{
if ((e.Error as SmtpException).Message.Contains("secure connection"))
{
(e.UserState as SmtpClient).EnableSsl = true;
(e.UserState as SmtpClient).SendAsync(objMailMsg, e.UserState);
}
else
MessageBox.Show("Error: " + e.Error.ToString());
}
else
MessageBox.Show("Error: " + e.Error.ToString());
}
There's a great example of how to do this with a "Service Broker" in Chapter 8 of Richard Kiessig's book "Ultra-Fast ASP.NET."
Here's the link to the book on the publisher's website where you can download the sample code from the book. Again, chapter 8...
http://apress.com/book/view/9781430223832

Categories

Resources