1

I am developing a winforms/database software. It is a software that will be used by everyone in the office, using the same database. There is a column which holds "datetime" of a task. Also there is a delay time for this task, what I want to do is, program should trigger sendMail() function if today's date is bigger than datetime + delaytime. How can I trigger this function, it should be user-independent?

void sendMail(string taskid, string subject, string message)
{

    try
    {

        SqlCommand komut = new SqlCommand();
        komut.CommandText = "select planner from db_owner.tbl_SpecificTask where TASKID = @taskid";
        komut.Parameters.AddWithValue("@taskid", TASKID);
        komut.Connection = Db.Db;
        komut.CommandType = CommandType.Text;
        SqlDataReader dr = komut.ExecuteReader();
        while (dr.Read())
        {

            MailMessage mail = new MailMessage();
            SmtpClient SmtpServer = new SmtpClient();
            mail.To.Add(dr[0].ToString());
            //mail.To.Add(dr[1].ToString());
            mail.From = new MailAddress("task.notification@tr.companyA.com");
            mail.Subject = subject;
            mail.IsBodyHtml = true;
            mail.Body = message;
            SmtpServer.Host = "hiddeninfo";
            SmtpServer.Port = hiddeninfo;
            SmtpServer.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
            try
            {
                SmtpServer.Send(mail);

            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception Message: " + ex.Message);
                if (ex.InnerException != null)
                    Debug.WriteLine("Exception Inner:   " + ex.InnerException);
            }

        }


    }
    catch (Exception ex)
    {
        MessageBox.Show("Error: " + ex);
    }
    finally
    {
        Db.Close();
    }

}
Cemil Çakmak
  • 149
  • 1
  • 12

1 Answers1

1

This should not be the responsibility of the WinForms application. Why?

  1. It will need coordination. If two or more local applications try to send the email, who should do it?
  2. It will spend a lot more computational time (as many times as the clients) than a single instance.
  3. The db will be hit like crazy

So what can you do. A couple of things actually.

Assuming service layer.

If your applications communicate via a service layer like a WebApi, the are worker processes. Running a background thread on a RESTful WebApi request this might be helpful.

Assuming the application speak directly to the database.

Create a new service on a server. Notice I did not explicitly say the database server, as it might not be able to access the internet, but a web server in the essence of it not having a downtime.

Create the service following a tutorial like this: https://learn.microsoft.com/en-us/dotnet/framework/windows-services/walkthrough-creating-a-windows-service-application-in-the-component-designer. This example is even polling as you do.

Use native app with scheduler

You can build a windows application and invoke with windows scheduler. If your application is .net core, you can even invoke from linux machines using cron jobs

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
  • Thank you for explanations, for 1; database should trigger this function, it won't be user-driven therefore I think coordination is not needed. You are right about others also, however I have limited time and the software is nearly ready. – Cemil Çakmak Dec 03 '19 at 08:28
  • If you have to do it in the WinForm, then look at the https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.backgroundworker?view=netframework-4.8 . It does not need to be started from a button. Be aware of the three points mentioned above though. The way you run your sql, make sure that the row is locked so that you won't have to do any coordination between the clients. – Athanasios Kataras Dec 03 '19 at 08:42