2016-10-19 1 views
0

데이터베이스의 데이터를 데이터 그램 뷰로 그리고 이메일을 보내는 메소드 인 datagridview로 가져 오는 메소드를 만들었습니다. 그래서처럼 코딩 :메쏘드를 실행할 때마다 Listview에 추가가되는지 확인하십시오.

// TODO: Prepare the email addresses 
     private void SendEmail() 
     { 
      // Get the email addresses according to bio_id 
      var rdr = new EmployeeDataAccess().GetBioIdEmail(); 
      while (rdr.HasRows && rdr.Read()) 
      { 
       dgvBioIdList.Rows.Add(rdr["bio_id"].ToString(), rdr["email_add"].ToString()); 
      } 

      // Get the time logs for each of the bio_id in the datagridview 
      Cursor.Current = Cursors.WaitCursor; 
      for (var i = 0; i < dgvBioIdList.Rows.Count; i++) 
      { 
       using (var cn = new DatabaseConnection().ConnectToMySql()) 
       { 
        const string query = @"SELECT MIN(scan_time) as 'TimeIn', MAX(scan_time) as 'TimeOut', 
        TIMEDIFF(MAX(scan_time),MIN(scan_time)) as difference 
        FROM `filtered_dates` 
        WHERE date BETWEEN @fromDate AND @toDate AND bio_id = @bioId 
        GROUP BY date 
        ORDER BY date asc"; 
        var cmd = new MySqlCommand(query, cn); 
        cn.Open(); 
        cmd.Parameters.AddWithValue("@fromDate", dtpStart.Text); 
        cmd.Parameters.AddWithValue("@toDate", dtpStop.Text); 
        cmd.Parameters.AddWithValue("@bioId", dgvBioIdList.Rows[i].Cells[0].Value); 
        rdr = cmd.ExecuteReader(); 

        // Create the message to send to the email 
        if (!rdr.HasRows) continue; 
        var message = "Time Logs for Bio ID: " + dgvBioIdList.Rows[i].Cells[0].Value; 
        message += Environment.NewLine; 
        message += @"Included dates: " + dtpStart.Text + @" to " + dtpStop.Text; 
        message += Environment.NewLine; 
        message += @"Email Address: " + dgvBioIdList.Rows[i].Cells[1].Value; 
        message += Environment.NewLine; 
        while (rdr.Read()) 
        { 
         message += rdr["TimeIn"] + @" - " + rdr["TimeOut"] [email protected]" = " +rdr["Difference"]; 
         message += Environment.NewLine; 
        } 

        // Actual sending of the email 
        SendingEmail(dgvBioIdList.Rows[i].Cells[0].Value.ToString(),dgvBioIdList.Rows[i].Cells[1].Value.ToString(), message, txtUserName.Text, txtPassword.Text); 
       } 
      } 
      Cursor.Current = Cursors.Default; 
     } 

     // Sending of the E-mail and to list the status of the sending in a listview 
     private void SendingEmail(string bioId, string recipient, string body, string userName, string password) 
     { 
      var mail = new MailMessage(); 
      var smtpServer = new SmtpClient("smtp.gmail.com"); 

      mail.From = new MailAddress(userName); 
      mail.To.Add(recipient); 
      mail.Subject = "Time Logs"; 
      mail.Body = body; 

      smtpServer.Port = 587; 
      smtpServer.Credentials = new System.Net.NetworkCredential(userName, password); 
      smtpServer.EnableSsl = true; 
      try 
      { 
       smtpServer.Send(mail); 
       string[] row = {bioId, recipient, "PASSED"}; 
       var listViewItem = new ListViewItem(row); 
       lvEmailStatus.Items.Add(listViewItem); 
       //Console.WriteLine(@"Successfully sent mail to " + recipient); 
      } 
      catch (Exception ex) 
      { 
       string[] row = { bioId, recipient, "FAILED" }; 
       var listViewItem = new ListViewItem(row); 
       lvEmailStatus.Items.Add(listViewItem); 
       Console.WriteLine(@"Failed sending mail " + recipient); 
       return; 
      } 

     } 

이 코드는 점을 제외하고 잘 작동이 목록보기는 DataGridView에있는 행의 각 반복을 통해 작성해야합니다. 무슨 일이 일어나는가? 그것은 먼저 datagridview에있는 모든 사람들에게 전자 메일을 보내고 그렇게하는 동안 프로그램은 약간 멈추지 만 계속 최소화하고 닫을 수는 있습니다. 전송이 끝나면 전달 또는 실패한 경우 전송 상태와 함께 목록보기에 데이터가 채워지는 시간이됩니다. 그러나 Console.Writeline에서이 작업을 수행하면 DataGridview의 다음 행으로 이동하기 전에 전송 상태를 볼 수 있습니다! 다음과 같아야합니다 - (행 선택) - (전자 메일 전송) - (목록보기 채워짐 참조) - (다음 행으로 이동) - (전자 메일 전송) - DataGridview의 마지막 행

귀하의 도움에 감사드립니다.

답변

0

귀하의 메서드가 UI 스레드에서 호출되었지만 처리 중에 UI 스레드를 릴리스하지 않았기 때문입니다. 무거운 과정에서 UI 스레드를 계속 사용하려면 asyncawait을 사용하는 것을 선호합니다.

+0

나는 그것을 사용할 필요가 있다고 생각했다. 이 비동기를 사용하고 기다리는 방법을 이해하는 것이 정말 어렵 기 때문에 다른 방법이 있기를 바랬습니다. 가끔은 때로는 작동하지 않게 만들 수 있습니다. 당신이 내 코드에서 이것을 어떻게 사용할 수 있는지 충분히 친절하게 보여줄 수 있다면 정말 멋지게 될 것입니다! – Ibanez1408

+0

이 줄을 사용하여 UI를 새로 고칠 수는 있지만 이는 부끄러운 일입니다. 'Dispatcher.Invoke (() => {}, DispatcherPriority.Render); ' http://stackoverflow.com/questions/15247594/confusion-about-refreshing-the-ui-in-wpf – cactuaroid

관련 문제