how to implement while loop for processing when clicking - c#

I hope you can help me with this problem. When I click a Email button, it takes few seconds to process before sending successfully. I need to put process image on but how to implement with "while" loop for processing.
Here is code: i think i should implement with client.Send(msg); for processing. How does it work? I will appreciate your example code. Thanks! (I am using C# and WPF)
private void BtnSendEmailClick(object sender, RoutedEventArgs e)
{
SmtpClient client = null;
MailMessage msg = null;
try
{
msg = new MailMessage
{
From = new MailAddress("me#hotmail.com", "Me Hotmail")
};
msg.To.Add(txtEmailAddress.Text);
msg.Priority = MailPriority.High;
msg.Subject = "Blah blah";
msg.Body =
"<!DOCTYPE html><html lang='en' xmlns='http://www.w3.org/1999/xhtml'>" +
"<head> </head>" +
"<body>" +
"<h3>Message</h3>" +
"<p>" + lblEmailMessage.Content + "</p>" +
"</body>" +
"</html>";
msg.IsBodyHtml = true;
client = new SmtpClient
{
Host = "smtp.live.com",
Port = 25,
EnableSsl = true,
UseDefaultCredentials = false,
Credentials = new NetworkCredential("me#hotmail.com", "password"),
DeliveryMethod = SmtpDeliveryMethod.Network
};
//how to implement while loop for processing
client.Send(msg);
lblMessage.Content = "Successfully sent to your Mail!";
}
catch (Exception ex)
{
lblMessage.Content = ex.Message;
}
}

You will need to return instantly, and use a BackgroundWorker to send the email. Once it is finished, you can use the Dispatcher to notify the GUI. See http://msdn.microsoft.com/en-us/magazine/cc163328.aspx for more details.
See also How to use WPF Background Worker.

Are you wanting to display an image to indicate that the program is doing something (progress indicator)?
In that case you need to do the work of sending the email on a separate thread. You can do this in several ways. The easiest (if you are using .NET 4) is to use the await and async keywords. Simply display the image before starting your work. You'll need to extract the code that actually sends the email into a new method also. Like this:
private void BtnSendEmailClick(object sender, RoutedEventArgs e)
{
// Display progress image
progressImage.Visibility = System.Windows.Visibility.Visible;
string errorMessage = await SendEmail();
if (errorMessage == null)
{
lblMessage.Content = "Successfully sent to your Mail!";
}
else
{
lblMessage.Content = errorMessage;
}
progressImage.Visibility = System.Windows.Visibility.Hidden;
}
private async Task<string> SendEmail()
{
try
{
var msg = new MailMessage
{
From = new MailAddress("me#hotmail.com", "Me Hotmail")
};
msg.To.Add(txtEmailAddress.Text);
msg.Priority = MailPriority.High;
msg.Subject = "Blah blah";
msg.Body =
"<!DOCTYPE html><html lang='en' xmlns='http://www.w3.org/1999/xhtml'>" +
"<head> </head>" +
"<body>" +
"<h3>Message</h3>" +
"<p>" + lblEmailMessage.Content + "</p>" +
"</body>" +
"</html>";
msg.IsBodyHtml = true;
var client = new SmtpClient
{
Host = "smtp.live.com",
Port = 25,
EnableSsl = true,
UseDefaultCredentials = false,
Credentials = new NetworkCredential("me#hotmail.com", "password"),
DeliveryMethod = SmtpDeliveryMethod.Network
};
//how to implement while loop for processing
client.Send(msg);
return "Successfully sent to your Mail!";
}
catch (Exception ex)
{
return ex.Message;
}
}
One final note: Be sure that you don't touch any UI components in your 'async' method as there is no guarantee that the code will be running on the UI thread. If you need more information returned from the async method you'll have to create a custom structure to contain the result and return it from that SendEmail() method.

Related

C# if statement not working

My code works within a local network and I know it will not work outside of the local network as I am using Dns.GetHostEntry to resolve the IP address to hostname and thats fine...
But my if statement is not working, I am getting error "No Host Found" message when trying to resolve hostname from different subnet.
I thought my if statement would stop this error but its not working, can someone help please or tell me how to fix it, code below...
public partial class _Default : System.Web.UI.Page
{
//public string IPaddr1 { get; private set; }
string serviceDesk = "eg#mail.co.uk";
string emailSubject = "MyPc";
string IPaddr = "";
string deviceName = "";
protected void Page_Load(object sender, EventArgs e)
{
getIP();
}
protected void getIP()
{
if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDER_FOR"] != null)
{
IPaddr = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDER_FOR"].ToString();
}
if (HttpContext.Current.Request.UserHostAddress.Length != 0)
{
IPaddr = HttpContext.Current.Request.UserHostAddress;
deviceName = Dns.GetHostEntry(IPAddress.Parse(IPaddr)).HostName;
}
if (HttpContext.Current.Request.UserHostAddress.Length != 0)
{
deviceName = "Device name could be found";
}
Label1.Text = "IP Address: " + " " + IPaddr;
Label2.Text = "PC Name: " + " " + deviceName;
}
private void EmailVerificationRequest(string recepientEmail, string subject)
{
try
{
using (MailMessage mailMessage = new MailMessage())
{
StringBuilder sbEmailBody = new StringBuilder();
sbEmailBody.Append("IP address " + IPaddr + "<br/>");
sbEmailBody.Append("Hostname " + " " + deviceName);
mailMessage.From = new MailAddress(ConfigurationManager.AppSettings["FromEmail"]);
mailMessage.Subject = subject;
mailMessage.Body = sbEmailBody.ToString();
mailMessage.IsBodyHtml = true;
mailMessage.To.Add(new MailAddress(recepientEmail));
SmtpClient smtp = new SmtpClient();
smtp.Host = ConfigurationManager.AppSettings["Host"];
smtp.Port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);
smtp.EnableSsl = Convert.ToBoolean(ConfigurationManager.AppSettings["EnableSsl"]);
System.Net.NetworkCredential NetworkCred = new System.Net.NetworkCredential();
NetworkCred.UserName = ConfigurationManager.AppSettings["UserName"];
NetworkCred.Password = ConfigurationManager.AppSettings["Password"];
if (string.IsNullOrWhiteSpace(NetworkCred.UserName))
{
smtp.UseDefaultCredentials = true;
}
else
{
smtp.Credentials = NetworkCred;
smtp.UseDefaultCredentials = false;
}
smtp.Port = int.Parse(ConfigurationManager.AppSettings["Port"]);
try
{
smtp.Send(mailMessage);
}
catch (SmtpException e)
{
}
}
}
catch
{
}
}
protected void Button1_Click(object sender, EventArgs e)
{
EmailVerificationRequest(serviceDesk, emailSubject);
Response.Redirect("~/message.aspx");
}
}
From the MSDN Documentation:
If the host name could not be found, the SocketException exception is returned with a value of 11001 (Windows Sockets error WSAHOST_NOT_FOUND). This exception can be returned if the DNS server does not respond. This exception can also be returned if the name is not an official host name or alias, or it cannot be found in the database(s) being queried.
Therefore, I suspect your code isn't getting as far as the third if condition because an exception is being thrown by the call to GetHostEntry(), which you're seeing as the 'error "No Host Found" message'.
The most straightforward way to deal with this is to use a try...catch block to catch the specific exception and handle it, something such as:
try
{
deviceName = Dns.GetHostEntry(IPAddress.Parse(IPaddr)).HostName;
}
catch (SocketException)
{
deviceName = "Device name could be found";
}
This says that if a SocketException occurs during the call to GetHostEntry(), the code is to jump to the catch block, rather than the exception stopping your application.
Note that this assumes that any SocketException means that the IP address wasn't found, but it could mean that the DNS server wasn't contactable, or some other error.
MSDN has quite a lot on exception handling and how try...catch blocks work.
Hope this helps
Before you get a value from a dictionary, you must check if the dictionary contains the key you pass. You achieve this by calling "Contains" method.
if (HttpContext.Current.Request.ServerVariables.Contains("HTTP_X_FORWARDER_FOR"))
{
// Your Code...
}
If you retrieve the content of a dictionary directly and the key you are requesting doesn't exist in the dictionary pairs, the dictionary doesn't return null. Instead, it throws KeyNotFoundException.

Send Email to admin at specific time everyday / be notified when stock levels are low by email

Does anyone know how i would code this:
to send an email to the admin/manager everyday at a specific time including a table from the database (Stock Table - which only has four pieces of stock) so they will be informed of their stock levels and if they need to reorder.
Or else
Something in which will send an email to the manager/ admin if one of these four stock levels are low informing them a certin materials/ piece of stock has reached the minimum level and to re order.
I have the code for sending an email:
protected void Button1_Click1(object sender, EventArgs e)
{
MailMessage mail = new MailMessage(from.Text, to.Text, subject.Text, body.Text);
SmtpClient Client = new SmtpClient(smtp.Text);
Client.Port = 587;
Client.Credentials = new System.Net.NetworkCredential(username.Text, password.Text);
Client.EnableSsl = true;
Client.Send(mail);
Response.Write("<script LANGUAGE='JavaScript' >alert('Mail Sent')</script>");
}
any help is welcomed!!!
Thank you!
You need a scheduler so you can schedule a daily task to check the stock levels and send an email if needed. You can achieve this using hangfire if you want to keep everything inside your asp.net application. Hangfire is a scheduler. Check https://www.hangfire.io/
The code would look like this
RecurringJob.AddOrUpdate(
() => {
//TODO: Check your Stock Table DB
var from = "noreply#<yourcompany>.com"
var to = "admin#<yourcompny>.com"
var subject = "Low stock"
var body = "The following items are low in stock : "
// TODO: append items to body variable
MailMessage mail = new MailMessage(from, to, subject, body);
SmtpClient Client = new SmtpClient(smtp.Text);
Client.Port = 587;
Client.Credentials = new System.Net.NetworkCredential(username.Text, password.Text);
Client.EnableSsl = true;
Client.Send(mail);},
Cron.Daily);
});
use Windows Service to Monitoring the data, hour and DB.
private void mainTimer_Tick(object sender, EventArgs e)
{
try
{
if (ConfigsHTM["exechour"] != null)
{
if (DateTime.Now.ToString("HH:mm:ss") == ConfigsHTM["exechour"].ToString())
{
ClassProcessing clsProc = new ClassProcessing();
clsProc.StartDate = DateTime.Now.AddDays(-1);
clsProc.EndDate = DateTime.Now.AddDays(-1);
clsProc.ProcessAll();
if (StatusHTM.Count > 0)
StatusHTM.Clear();
StatusHTM.Add("locationstatus","Todas as Unidades");
StatusHTM.Add("typestatus","Agendado");
StatusHTM.Add("exechourstatus", DateTime.Now.ToString("F"));
if (clsProc.ReprocessingDone)
StatusHTM.Add("statusstatus","OK");
else
StatusHTM.Add("statusstatus", "Falhou");
ClassStatus clsStt = new ClassStatus();
clsStt.StatusHT = StatusHTM;
clsStt.SaveStatus();
GetStatus();
}
}
}
catch (Exception ex)
{
ClassLog clsLog = new ClassLog();
clsLog.EventData = "Falha ao Iniciar a Execução do Aplicativo";
clsLog.ErrorLog();
clsLog.EventData = ex.ToString();
clsLog.ErrorLog();
}
}

smtp code executes even though I stop the process

I'm using the following code to open a text file and send emails to the people listed and changing the subject to include their ids. The issue i'm having is that the first time through testing I stopped the debugger on the subject line. The next thing I know I'm getting the test email. How could the code continue to execute even when I stopped the debugger?
Here is my code:
protected void btnTest_Click(object sender, EventArgs e)
{
string sFilePath = #"C:\email\" + ddlYear.SelectedItem.Value + "-" + ddlMonth.SelectedItem.Value + "_Num.txt";
using (TextFieldParser parser = new TextFieldParser(sFilePath))
{
parser.TextFieldType = FieldType.FixedWidth;
parser.SetFieldWidths(4, -1);
int iRowCnt = 1;
while (!parser.EndOfData)
{
string[] sCurrRow = parser.ReadFields();
try
{
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage("test#test.com", sCurrRow[1].ToString());
message.Subject = txtSubject.Text + " - ID #" + sCurrRow[0].ToString() ;
message.IsBodyHtml = Convert.ToBoolean(ddlFormat.SelectedValue);
message.Body = txtMsg.Text;
System.Net.Mail.SmtpClient mailClient = new System.Net.Mail.SmtpClient();
mailClient.Host = "testSMTP.test.com";
mailClient.Credentials = new System.Net.NetworkCredential("TestSMTP", "TESTING"); //Username and password changes
mailClient.Send(message);
this.InsEmailDB(iRowCnt, iRowCnt, sCurrRow[1].ToString());
iRowCnt++;
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
Stopping the debugger doesn't terminate the program, it just stops "watching" it-- the program will still run to completion.
Debugging as it's name suggests, is to error free the application. It only show you how it is executing. Stopping debug doesn't mean stopping application. And I think receiving test mail isn't big issue.

How can i make that my application will check and get specific email subject?

I have this class that send emails. I log in using my isp email and send it to my gmail email.
Now i want to do that when someone will download/get my application it will check each 1 minute for my gmail account address for a specific email with a specific subject so the email subject will be like a code for example the email subject will be: 16765645
Once the application downloaded the email i want to display the email content in a textBox and also to write on a text file the email content. Also i want that the application will check the email time download after it was downloaded so the application will not download the same email all the time.
This is how i'm sending emails today:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DannyGeneral;
using System.Net.Mail;
using System.Net;
using System.Net.Mime;
using System.IO;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
namespace Diagnostic_Tool_Blue_Screen
{
class SendEmail
{
private MailMessage photosmessage;
public bool textfilessendended;
public bool photossendended;
Label lbl1;
Label lbl3;
Button SendLogFile;
MailMessage message;
MailMessage docmessage;
public int timerdelay;
public Timer timer3;
public SendEmail(Label label2, Label label3, Button slf, int timerd, Timer timer)
{
textfilessendended = false;
photossendended = false;
lbl1 = label2;
lbl3 = label3;
SendLogFile = slf;
timerdelay = timerd;
timer3 = timer;
}
public void SendLogger()
{
string log_file_name = "logger.txt";
string logger_file_to_read = Path.GetDirectoryName(Application.LocalUserAppDataPath) + #"\log";
string LoggerFile = Path.Combine(logger_file_to_read, log_file_name);
try
{
MailAddress from = new MailAddress("test#gmail.com", "User " + (char)0xD8 + " Name",
System.Text.Encoding.UTF8);
MailAddress to = new MailAddress("test#test.net");
message = new MailMessage(from, to);
message.Body = "Please check the log file attachment i have some bugs.";
string someArrows = new string(new char[] { '\u2190', '\u2191', '\u2192', '\u2193' });
message.Body += Environment.NewLine + someArrows;
message.BodyEncoding = System.Text.Encoding.UTF8;
message.Subject = "Log File For Checking Bugs" + someArrows;
message.SubjectEncoding = System.Text.Encoding.UTF8;
Attachment myAttachment = new Attachment(LoggerFile, MediaTypeNames.Application.Octet);
message.Attachments.Add(myAttachment);
SmtpClient ss = new SmtpClient("smtp.gmail.com", 587);
ss.SendCompleted += new SendCompletedEventHandler(ss_SendCompleted);
ss.EnableSsl = true;
ss.Timeout = 10000;
ss.DeliveryMethod = SmtpDeliveryMethod.Network;
ss.UseDefaultCredentials = false;
ss.Credentials = new NetworkCredential("meuser", "mepassword");
string userState = "test message1";
ss.SendAsync(message, userState);
lbl3.Enabled = true;
lbl3.Visible = true;
lbl3.BackColor = Color.DarkSeaGreen;
lbl3.Text = "Sending email please wait";
SendLogFile.Enabled = false;
}
catch (Exception errors)
{
Logger.Write("Error sending message :" + errors);
}
}
private void ss_SendCompleted(object sender, AsyncCompletedEventArgs e)
{
timerdelay = 0;
timer3.Start();
String token = (string)e.UserState;
if (e.Cancelled)
{
Logger.Write("[{0}] Send canceled." + token);
SendLogFile.Enabled = true;
}
if (e.Error != null)
{
lbl3.Enabled = true;
lbl3.Visible = true;
lbl3.BackColor = Color.DarkSeaGreen;
lbl3.Text = "There was a problem with sending the log file please try again later and check the log file for more information";
Logger.Write("There was a problem with sending the log file please try again later and check the log file for more information :" + e.Error.ToString());
SendLogFile.Enabled = true;
}
else
{
SendLogFile.Enabled = true;
message.Dispose();
lbl3.Enabled = true;
lbl3.Visible = true;
lbl3.BackColor = Color.DarkSeaGreen;
lbl3.Text = "Email have been sent successfully";
Logger.Write("Attached log file have been emailed successfully");
lbl1.BringToFront();
lbl1.Visible = true;
lbl1.Text = "The log file have been sent on: " + DateTime.Now;
}
}
The idea in general is to use the email like a server to transfer a push messages like updates. So when a user is downloading my program and run if any X minutes there a new email he will see it in the program like a new update.
The idea in general is to use the email like a server to transfer a push messages like updates. So when a user is downloading my program and run if any X minutes there a new email he will see it in the program like a new update.
Honestly, this sounds more like a job for a web service than an email client. You can have your client periodically consume a web service that publishes the latest update message. It will be much simpler for you to implement, and there is a plethora of documentation for doing so.
If you let web services do all the heavy lifting for you, you'll have less code to write, and have to worry less about making a secure, stable solution. Using email to do this seems very kludgy.

Using Asp.Net to SendAsync emails but Page still waits?

I don't want the user to wait for page completing the sending processes, so I'm thought of using SendAsync in ASP.NET 3.5. But for after debuging, I found that the Main Thread still waits.
Main: Call send email function...
mailSend: Configuring....
mailSend: setting up incorrect port....
mailSend: Attempt now to send....
mailSend: End of Line
Main: Email Function call finish.
Main: Proccess Complete!
mailComp: Sending of mail failed, will try again in 5 seconds...
mailComp: Retrying...
mailComp: Send successful!
mailComp: End of Line
Now the I placed incorrect port setting so the first email fails, and test to see if the second time it will be successful. Even with the correct port, the page still waits. Only after mailComp function is finish is when the Page is finally posted. Is this some limitation to SendAsyn?
And here some code, not sure if this will be helpful.
protected void btnReset_Click(object sender, EventArgs e)
{
try
{
DataContext db = new DataContext();
var query = from u in db.Fish
where u.Username == txtUsername.Text & u.Email == txtEmail.Text
select new { u.Username, u.Email };
if (query.Count() != 0)
{
User user = new User();
String token = user.requestPasswordReset(txtUsername.Text);
String URL = Request.Url.AbsoluteUri.ToString() + "?token=" + token;
String body = "Reseting you password if you \n" + URL + "\n \n ";
Untilty.SendEmail(txtEmail.Text, "Reseting Password", body);
litTitle.Text = "Message was sent!";
litInfo.Text = "Please check your email in a few minuets for further instruction.";
viewMode(false, false);
}
else
{
litCannotFindUserWithEmail.Visible = true;
}
}
catch (Exception ex)
{
Debug.Write("Main: Exception: " + ex.ToString());
litInfo.Text = "We are currently having some technically difficulty. Please try again in a few minuets. If you are still having issue call us at 905344525";
}
}
///
public static class Utility
///
public static void SendEmail(string recipient, string subject, string body)
{
MailMessage message = new MailMessage();
message.To.Add(new MailAddress(recipient));
message.From = new MailAddress(fromaddress, "Basadur Profile Website");
message.Subject = subject;
message.Body = body;
Send(message);
}
private static void Send(MailMessage msg)
{
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Credentials = new System.Net.NetworkCredential(fromaddress, mailpassword);
smtp.EnableSsl = true;
Debug.WriteLine("mailSend: setting up incorrect port....");
smtp.Port = 5872; //incorrect port
smtp.SendCompleted += new SendCompletedEventHandler(smtp_SendCompleted);
smtp.SendAsync(msg, msg);
}
static void smtp_SendCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
var msg = (MailMessage)e.UserState;
if (e.Error != null)
{
System.Threading.Thread.Sleep(1000 * 5);
try
{
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Credentials = new System.Net.NetworkCredential(fromaddress, mailpassword);
smtp.EnableSsl = true;
smtp.Port = 587;
smtp.Send(msg);
}
catch (Exception ex)
{
Debug.WriteLine("mailComp: Failed for the second time giving up.");
}
}
}
In .NET 4.5.2, a method was added for scheduling tasks in the background, independent of any request: HostingEnvironment.QueueBackgroundWorkItem().
HostingEnvironment.QueueBackgroundWorkItem() is in the System.Web.Hosting namespace.
The remarks in the documentation say:
Differs from a normal ThreadPool work item in that ASP.NET can keep
track of how many work items registered through this API are currently
running, and the ASP.NET runtime will try to delay AppDomain shutdown
until these work items have finished executing.
Meaning, you can fire off a task in a fire-and-forget manner with a greater confidence in it not being terminated when the app domain recycles.
Usage is like:
HostingEnvironment.QueueBackgroundWorkItem(cancellationToken =>
{
try
{
// do work....
}
catch(Exception)
{
//make sure nothing can throw in here
}
});
These days you can use a Task to dispatch work to the thread pool. Just use
Task.Run(()=> Untilty.SendEmail(txtEmail.Text, "Reseting Password", body));
The debugger seems to force things to be single threaded. If you step through, you may find that you end up jumping between two different files, as each step moves a different thread.
Try to add some logging in there and run without debugging.
Using the below code you can send async emails in asp.net with SmtpClient.
ThreadPool.QueueUserWorkItem(callback =>
{
var mailMessage = new MailMessage
{
...
};
//if you need any references in handlers
object userState = new ReturnObject
{
MailMessage = mailMessage,
SmtpClient = smtpServer
};
smtpServer.SendCompleted += HandleSmtpResponse;
smtpServer.SendAsync(mailMessage, userState);
});
Use threading:
// Create the thread object, passing in the method
// via a ThreadStart delegate. This does not start the thread.
Thread oThread = new Thread(new ThreadStart(SendMyEmail));
// Start the thread
oThread.Start();
Here is the source, it has a full threading tutorial.

Categories

Resources