2017-09-16 6 views
-1

私のプログラムで現在問題が発生しています。私はsmtpで電子メールを送信する方法を習得しようとしています。 button1をクリックしようとすると、プログラムがフリーズして何も起こりません。 PS:明らかに、私は電子メールとパスワードを「電子メール」と「パスワード」に変更してからこれを送信しました。 PS2:私はポルトガル語で自分のコードを書いていますので、変数や "x"と考えるだけでは理解できないことがあります。smtpで電子メールを送信しようとしたときにプログラムがフリーズする

EDIT:単純な行で問題を解決しました。プログラムにポートがありません。同じ問題を抱えていますが、smtp.Port = 587を追加するだけです。 。以下

コード:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Net.Mail; 
using MySql.Data.MySqlClient; 
using System.Net; 

namespace Inicio 
{ 
    public partial class Email : Form 
    { 
     MySqlConnection con = new MySqlConnection(@"Data Source=localhost;port=3306;Initial Catalog=digital wallet;User ID=root;password="); 
     public Email() 
     { 
      InitializeComponent(); 
     } 

     private void SendEmail() 
     { 

      if (textBox1.Text == "" || textBox2.Text == "") 
      { 
       MessageBox.Show("Preencha todos os campos", "Erro", 
       MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 
      else 
      { 
       int i = 0; 
       con.Open(); 
       MySqlCommand cmd = con.CreateCommand(); 
       cmd.CommandType = CommandType.Text; 
       cmd.CommandText = "select EMAIL from conta where EMAIL = @email and LOGIN = @login "; 
       cmd.Parameters.AddWithValue("@email", textBox2.Text); 
       cmd.Parameters.AddWithValue("@login", textBox1.Text); 
       cmd.ExecuteNonQuery(); 
       DataTable dt = new DataTable(); 
       MySqlDataAdapter da = new MySqlDataAdapter(cmd); 
       da.Fill(dt); 
       i = Convert.ToInt32(dt.Rows.Count.ToString()); 

       if (i == 0) 
       { 
        MessageBox.Show("Login ou email inválidos", "Erro", 
        MessageBoxButtons.OK, MessageBoxIcon.Error); 
       } 
       else 
       { 
        cmd.CommandText = "select * from CONTA where LOGIN = @login"; 
        cmd.ExecuteNonQuery(); 

        string senha = ""; 
        string email = ""; 

        MySqlDataReader reader = cmd.ExecuteReader(); 
        while (reader.Read()) 
        { 
         senha = reader.GetString("SENHA"); 
         email = reader.GetString("EMAIL"); 
        } 

        reader.Close(); 

        using (SmtpClient smtp = new SmtpClient()) 
        { 
         smtp.Host = "outlook.com"; 
         smtp.UseDefaultCredentials = false; 
         NetworkCredential netCred = new NetworkCredential("email", "password"); 
         smtp.Credentials = netCred; 
         smtp.EnableSsl = true; 

         using (MailMessage msg = new MailMessage("email", email)) 
         { 
          msg.Subject = "Recuperação de senha."; 
          StringBuilder sb = new StringBuilder(); 
          sb.AppendLine("A sua senha é atual é: " + senha + Environment.NewLine); 
          sb.AppendLine("Obrigado," + Environment.NewLine); 
          sb.AppendLine("Digital wallet. " + Environment.NewLine); 
          msg.Body = sb.ToString(); 
          msg.IsBodyHtml = false; 
          smtp.Send(msg); 
         } 
        } 
       } 
      } 
     } 
     private void button1_Click(object sender, EventArgs e) 
     { 
      SendEmail(); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      this.Close(); 
     } 
    } 
} 

答えて

0

あなたはGUIの環境には、実行されています。イベントはできるだけ早く返さなければなりません。それ以外の場合、GUIは「ロックアップ」されます。特にディスクやネットワークの活動は長期間実行される傾向があります。 GUIロックを避けるには、マルチタスキングのいくつかの形式を適用して(長い実行操作をその代替タスクに移動する)必要があります。

初心者の方には、マルチタスクにBackgroundWorkerを使用することをお勧めします。 Async ... awaitはより高度です。

編集:ここに私のWinForms + BackgroundWorkerサンプルコードがあります。正しく使用し始めるのに役立ちます。

#region Primenumbers 
 
private void btnPrimStart_Click(object sender, EventArgs e) 
 
{ 
 
\t if (!bgwPrim.IsBusy) 
 
\t { 
 
\t \t //Prepare ProgressBar and Textbox 
 
\t \t int temp = (int)nudPrim.Value; 
 
\t \t pgbPrim.Maximum = temp; 
 
\t \t tbPrim.Text = ""; 
 

 
\t \t //Start processing 
 
\t \t bgwPrim.RunWorkerAsync(temp); 
 
\t } 
 
} 
 

 
private void btnPrimCancel_Click(object sender, EventArgs e) 
 
{ 
 
\t if (bgwPrim.IsBusy) 
 
\t { 
 
\t \t bgwPrim.CancelAsync(); 
 
\t } 
 
} 
 

 
private void bgwPrim_DoWork(object sender, DoWorkEventArgs e) 
 
{ 
 
\t int highestToCheck = (int)e.Argument; 
 
\t //Get a reference to the BackgroundWorker running this code 
 
\t //for Progress Updates and Cancelation checking 
 
\t BackgroundWorker thisWorker = (BackgroundWorker)sender; 
 

 
\t //Create the list that stores the results and is returned by DoWork 
 
\t List<int> Primes = new List<int>(); 
 
\t 
 

 
\t //Check all uneven numbers between 1 and whatever the user choose as upper limit 
 
\t for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2) 
 
\t { 
 
\t \t //Report progress 
 
\t \t thisWorker.ReportProgress(PrimeCandidate); 
 
\t \t bool isNoPrime = false; 
 

 
\t \t //Check if the Cancelation was requested during the last loop 
 
\t \t if (thisWorker.CancellationPending) 
 
\t \t { 
 
\t \t \t //Tell the Backgroundworker you are canceling and exit the for-loop 
 
\t \t \t e.Cancel = true; 
 
\t \t \t break; 
 
\t \t } 
 

 
\t \t //Determin if this is a Prime Number 
 
\t \t for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2) 
 
\t \t { 
 
\t \t \t if (PrimeCandidate % j == 0) 
 
\t \t \t \t isNoPrime = true; 
 
\t \t } 
 

 
\t \t if (!isNoPrime) 
 
\t \t \t Primes.Add(PrimeCandidate); 
 
\t } 
 

 
\t //Tell the progress bar you are finished 
 
\t thisWorker.ReportProgress(highestToCheck); 
 

 
\t //Save Return Value 
 
\t e.Result = Primes.ToArray(); 
 
} 
 

 
private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e) 
 
{ 
 
\t pgbPrim.Value = e.ProgressPercentage; 
 
} 
 

 
private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
 
{ 
 
\t pgbPrim.Value = pgbPrim.Maximum; 
 
\t this.Refresh(); 
 

 
\t if (!e.Cancelled && e.Error == null) 
 
\t { 
 
\t \t //Show the Result 
 
\t \t int[] Primes = (int[])e.Result; 
 

 
\t \t StringBuilder sbOutput = new StringBuilder(); 
 

 
\t \t foreach (int Prim in Primes) 
 
\t \t { 
 
\t \t \t sbOutput.Append(Prim.ToString() + Environment.NewLine); 
 
\t \t } 
 

 
\t \t tbPrim.Text = sbOutput.ToString(); 
 
\t } 
 
\t else 
 
\t { 
 
\t \t tbPrim.Text = "Operation canceled by user or Exception"; 
 
\t } 
 
} 
 
#endregion

+0

はまあ...私がやるべき仕事を持っているようだ ダニエルについてお役に立てば幸いです。 –

0

、あなたのSQLクエリを処理するSMTPサーバに接続し、サーバーにメールデータを転送するには時間がかかります。あなたはUIスレッドですべてのものを実行するので、フォームはフリーズします。

は、フォームにBackgroundWorkerを追加.DoWork.RunWorkerCompletedのイベントハンドラを追加し、DoWork機能にSQLおよびSMTPのものを追加します。

ボタン1で、.RunWorkerAsyncでBackgroundWorkerを起動します。 TextBox1とTextBox2の内容で文字列配列をこの関数に渡します。 DoWork関数からそれらの要素にアクセスすることはできないので、これを行う必要があります。オプションで、ワーカーがすでにアクティブである場合は、.IsBusyで確認できます。ワーカーを起動した後、UIをロックするか、またはそのようなメッセージを表示して、バックグラウンドプロセスが実行中であることをユーザーに伝える必要があります。これをButton1Click関数から行います。

次に、.DoWork関数を変更して、渡された文字列配列を抽出します。これは、渡されたDoWorkEventArgs.Argumentsにアクセスして、RunWorkerAsyncに渡した型にキャストして文字列配列にします。 TextBoxアクセスを配列値にスワップします。

RunWorkerCompletedの機能では、UIのロックを解除する必要があります。

スタートのBackgroundWorkerについて読んで、あなたは「行ってメールデータを転送、SMTPサーバに接続し、SQLのデータを収集し、」進捗状況について、ユーザ、のようなものを通知する進捗報告機能を使用することができます...

+0

だから、コードは間違いなく正しいですか? –

+0

私はプログラムを実行したままにして、動作時間が限界を超えているという例外を受け取ります。 –

+0

操作制限時間超過は、ネットワーク側で何か問題が発生したことを意味します。間違った資格情報またはプロトコル。サーバーが見つからない。そんな感じ。あなたは内部の例外を調べて、正確に何かを理解する必要があります。そのようなタイムアウトに遭遇するリスクは、Networkingを常にマルチタスクにする1つの理由です。 – Christopher

0

Luan Teixeira、

Asynchronous Programming with Async and Awaitを見てください。それがあなたの問題を解決します。

私が言っていることを実証する。このコードをチェックしてください。

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 
    private async Task SendEmail() 
    { 

     if (textBox1.Text == "" || textBox2.Text == "") 
     { 
      MessageBox.Show("Preencha todos os campos", "Erro", 
      MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
     else 
     { 
      await Email.SendEmail(); 

      MessageBox.Show("Nice"); 
     } 
    } 
    private async void button1_Click(object sender, EventArgs e) 
    { 
     await SendEmail(); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     this.Close(); 
    } 
} 

public class Email 
{ 
    public async static Task SendEmail() 
    { 
     await Task.Delay(15000); 
    } 
} 

テキストボックス1とテキストボックス2に何かを書き込んでボタンをクリックできます。 15秒間待ってください(私は15秒かかるかもしれない本当に巨大なタスクをシミュレートしています)。一方、ユーザーインターフェイスがフリーズしていないことがわかります。ウィンドウを動かすことができます。 15秒後に「Nice」というメッセージが届きます。

私のコードでは、巨大なタスクがGUIスレッドで実行されていないためです。

はそれが 種類が

+0

ありがとう、私はこれを見て回ります。 –

関連する問題