2

Windows アプリケーション開発を学び始めたばかりで、1 つの Windows アプリケーションを開発するための自己学習プロジェクトが与えられました。メールを送信するアプリケーションを作成しようとしています。それを処理するクラスを作成しましたMsgSender.cs。メインフォームからそのクラスを呼び出すと、次のエラーが発生します

System.InvalidOperationException が処理されませんでした。

エラーメッセージ -->

クロススレッド操作が無効です: コントロール 'pictureBox1' は、それが作成されたスレッド以外のスレッドからアクセスされました。

スタックトレースは次のとおりです。

System.InvalidOperationException was unhandled
Message=Cross-thread operation not valid: Control 'pictureBox1' accessed from a thread other than the thread it was created on.
Source=System.Windows.Forms
StackTrace:
   at System.Windows.Forms.Control.get_Handle()
   at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
   at System.Windows.Forms.Control.set_Visible(Boolean value)
   at UltooApp.Form1.sendMethod() in D:\Ultoo Application\UltooApp\UltooApp\Form1.cs:line 32
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
InnerException: 

コード:

private void btnSend_Click(object sender, EventArgs e)
    {
        pictureBox1.Visible = true;
        count++;
        lblMsgStatus.Visible = false;
        getMsgDetails();
        msg = txtMsg.Text;

        Thread t = new Thread(new ThreadStart(sendMethod));
        t.IsBackground = true;
        t.Start();
    }

    void sendMethod()
    {
        string lblText = (String)MsgSender.sendSMS(to, msg, "hotmail", uname, pwd);
        pictureBox1.Visible = false;
        lblMsgStatus.Visible = true;
        lblMsgStatus.Text = lblText + "\nFrom: " + uname + " To: " + cmbxNumber.SelectedItem + " " + count;
    }
4

1 に答える 1

7

You can access Form GUI controls in GUI threadそして、例外を取得する理由である外部の GUI スレッドにアクセスしようとしています。MethodInvoker を使用して、GUI スレッドのコントロールにアクセスできます。

void sendMethod()
{
    MethodInvoker mi = delegate{
       string lblText = (String) MsgSender.sendSMS(to, msg, "hotmail", uname, pwd);
       pictureBox1.Visible = false;
       lblMsgStatus.Visible = true;
       lblMsgStatus.Text = 
             lblText + "\nFrom: " + uname + 
             " To: " + cmbxNumber.SelectedItem + " " + count;
   }; 

   if(InvokeRequired)
       this.Invoke(mi);
}
于 2012-11-16T05:50:46.033 に答える