2012-03-19 11 views
1

私はwebseriveに接続します。 Webサービスが接続されている間、私はそれの中にアニメーションGIFを持つ待っているフォームを持っていると思います。待機中のフォームは正しく表示されますが、アニメーションは固定されていません。C#スレッドと待ち受けのフォーム

誰でも助けてくれますか?私はすでに試みました:DoEventsしかし、GIFはまだアニメーションされていません。

 // Create the new thread object 
     Thread NewThread = new Thread(new ThreadStart(RunThread));   

     // Start the new thread. 
     NewThread.Start(); 

     // Inform everybody that the main thread is waiting 
     FRM_Wait waitingDialog = new FRM_Wait(); 
     waitingDialog.Show(); 
     waitingDialog.Activate(); 
     Application.DoEvents(); 

     // Wait for NewThread to terminate. 
     NewThread.Join(); 

     // And it's done. 
     waitingDialog.Close(); 
     MessageBox.Show("Upload erfolgreich erledigt.", "Upload Erfolgreich", 
      MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 
    } 

    public void RunThread() 
    {   
     mfsportservicedev.ServiceSoapClient servicedev = new mfsportservicedev.ServiceSoapClient(); 

     int status = servicedev.addEvent(videosNames, videos);   
    } 
+0

GIFはどこでアニメーション化されていますか?彼の親は誰ですか?私はアニメーションgifがどこにあるのかわからない。 – gbianchi

答えて

3

JoinをUIスレッド内からスレッドに呼び出さないでください。その代わりに、タスクが完了するまで(例えばボタン)操作したくないコントロールを無効にしてから、操作が完了したらをUIスレッドにコールします。そのため、「完了しました」コードを新しいメソッドは、操作の最後に呼び出されます。 .NET 4を使用している場合は、「進行中のタスク」を表現しやすくするためにTPLを使用することをお勧めします。 (これは、.NET 4.5で非同期操作を行う慣用的な方法になるための良いスタートです。)

+0

はい、それは 'GUIイベントハンドラで待っている'です。これは「私の浮動小数点演算は3.0の代わりに2.9999998を与えます」 –

1

問題はあなたの参加から来ています。 joinは同期的なので、基本的には、スレッドが作業を終えるまでUIを待機させています。

あなたのUIに戻るには、コールバック関数を使用します。

編集:skeetified

+0

「skeetified」より一般的になっていますか?ああ、厄介!すぐに医療援助を求めてください。 –

0

あなたの問題となってIVEはここにある:

NewThread.Join(); 

このブロックUIスレッドNewThreadが終了するまで。

ここでそれを行うための一つの方法です:

private myDelegate; 
// ... 
myDelegate = new Action(RunThread); 
myDelegate.BeginInvoke(new AsyncCallback(MyCallback),null); 
// You RunThread method is now running on a separate thread 
// Open your wait form here 
// ... 
// This callback function will be called when you delegate ends 
private void MyCallback(IAsyncResult ar) 
{ 
    myDelegate.EndInvoke(ar); 
    // Note this is still not the UI thread, so if you want to do something with the UI you'll need to do it on the UI thread. 
    // using either Control.Invoke (for WinForms) or Dispatcher.Invoke (for WPF) 
} 
0

Thread.Joinはそれがあなたの問題であるので、メッセージをポンプしないブロッキング呼び出しです。通常は、UIスレッドをブロックするような種類の同期メカニズムを呼び出さないようにすることをお勧めします。

ここでは、TaskクラスとInvokeマーシャリングテクニックを使用するソリューションがあります。

private void async InitiateWebService_Click(object sender, EventArgs args) 
{ 
    FRM_Wait waitingDialog = new FRM_Wait(); 
    waitingDialog.Show(); 

    Task.Factory.StartNew(
    () => 
    { 
     mfsportservicedev.ServiceSoapClient servicedev = new mfsportservicedev.ServiceSoapClient(); 
     int status = servicedev.addEvent(videosNames, videos); 
     waitingDialog.Invoke(
     (Action)(() => 
     { 
      waitingDialog.Close(); 
     })); 
    }); 
} 

ここでは、raw Threadを使用したソリューションです。

private void async InitiateWebService_Click(object sender, EventArgs args) 
{ 
    FRM_Wait waitingDialog = new FRM_Wait(); 
    waitingDialog.Show(); 

    var thread = new Thread(
    () => 
    { 
     mfsportservicedev.ServiceSoapClient servicedev = new mfsportservicedev.ServiceSoapClient(); 
     int status = servicedev.addEvent(videosNames, videos); 
     waitingDialog.Invoke(
     (Action)(() => 
     { 
      waitingDialog.Close(); 
     })); 
    }); 

    thread.Start(); 
} 

C#5.0は、新しいasyncawaitキーワードとパターンのこの種は、さらに簡単になります。


private void async InitiateWebService_Click(object sender, EventArgs args) 
{ 
    FRM_Wait waitingDialog = new FRM_Wait(); 
    waitingDialog.Show(); 

    await Task.Run(
    () => 
    { 
     mfsportservicedev.ServiceSoapClient servicedev = new mfsportservicedev.ServiceSoapClient(); 
     int status = servicedev.addEvent(videosNames, videos);   
    }); 

    waitingDialog.Close(); 
} 
はまだ発売されていません。

+0

お返事ありがとうございました!あなたは私をたくさん助けました。 – user1201412

関連する問題