2012-04-04 19 views
0

UIを更新するためにスレッドを使用するwinformアプリケーションに問題があります。私のアプリケーションはクラウドからのファイルのアップロードとダウンロードを行います。同時に、同じウィンドウにネットワーク速度の詳細も表示しています。これらの3つの操作(アップロード、ダウンロード、n/w速度の表示)は3つの異なるスレッドによって呼び出されます。問題は、私がダウンロード/アップロードを開始すると、ウィンドウ全体がフリーズし、n/w速度表示がリフレッシュされない(1秒間隔でリフレッシュするように書き込まれる)という問題です。何が問題だろうか?前もって感謝します。Winformとスレッド(C#)

コードは次のとおりです...ダウンロード用に書いたのと同じ方法です。 ** Upload **を最初に呼び出し、次に** Download **を1つずつ呼び出すと、最初のスレッドは一時停止し、スレッドの開始をダウンロードします。一度**ダウンロード**が行われると**アップロード**が続行されます。それは並行していません。また、UIは他のボタンのクリックやウィンドウのサイズ変更、アクションの移動に対してすぐには反応しません。

public delegate void UploadDelgt(); 
UploadDelgt UpldDlgtObj; 
private void Form1_Load(object sender, EventArgs e) 
{ 
    UpldDlgtObj = new UploadDelgt(DoUpload); 
} 

public void load() 
{ 
    Form1 form = this; 
    form.Invoke(UpldDlgtObj); 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    thrd = new Thread(new ThreadStart(load)); 
    thrd.Start(); 
    thrd.IsBackground = true; 
} 

public void DoUpload() 
{ 
//uploads file block by block and updates the progressbar accordingly.. 
} 
+3

コードを入力する必要があります。 – adt

+2

あなたのコードはあなたが思っていることをしていないと思います。見ることなく言うのは難しい。確かに、メインのGUIスレッドがラベルをアップさせるのを止めることが必要です。 – Jodrell

+1

ネットワーク速度のようなパフォーマンスデータを表示するのは、通常、スレッドからの通知/シグナリングではなく、GUIスレッドタイマーによって行われます。ネットワークの詳細が速すぎて変更に効率的かつ効果的な直接シグナリングができず、GUI入力キューが詰まる傾向があります。 –

答えて

1

あなたのUIがフリーズ。 MSDNInvokeExecutes the specified delegate on the thread that owns the control's underlying window handle. DoUploadは別のスレッドで呼び出されていると考えられますが、それはInvokeで呼び出されているため、GUIスレッド(フォームハンドルを所有)で実行されています。

+0

お返事ありがとうございます。私はあなたの言ったことに同意します。しかし、私がdelegate invokeを使用しないと、CrossThreadOperation例外がスローされます(UIのprogressbarを更新中)。私はデリゲートを使用して解決策が見つかりました。どうすればこの問題を解決できますか? –

+1

DoUploadメソッドを別のスレッドで(Invokeなしで)直接呼び出すことをお勧めします。このメソッドの内部では、Invokeを使用して進行状況情報を更新します。 [this](http://dotnetpad.net/ViewPaste/U3mHFc3hskmVQUvq8DGmdw#c0,c2,c4)のようなものです。 UIをあまり頻繁に更新しないようにしてください。そうしないと、UIがあまりにも遅くなることがあります。 –

+0

ありがとうございました。これは私の問題を解決しました。 –

2

これら3つの操作(アップロード、ダウンロード、表示N/W速度)は、3つの異なるスレッドによって呼び出されます。問題は、ダウンロード/アップロードを開始するとウィンドウ全体がフリーズする

ワーカースレッドの1つがUIスレッドをブロックしています。これらの操作のいずれもUIスレッド上で行われていないことを確認しますと、ここで説明するように、あなたはInvokeRequired/Invokeを使用すること:あなたのload方法でform.Invokeを呼び出しているので、http://www.codeproject.com/Articles/37642/Avoiding-InvokeRequired