0

Flickr.net API を使用して画像をアップロードしようとしています。画像はアップロードされますが、ユーザー インターフェイスがフリーズします。バックグラウンド ワーカーにアップロード用のコードを挿入しました。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    foreach (var item in imagelist)
    {
        flickr.UploadPicture(item, Path.GetFileName(item), null, null, true, false, true);
    }
    MessageBox.Show("Success");
}

flickr オブジェクトは、以前に別のフォームから作成され、このフォームに渡されます。if(worker.IsBusy==false){backgroundWorker1.RunWorkerAsync();}ボタンがクリックされるとワーカーを呼び出します。

4

2 に答える 2

2

これには 2 つの一般的な原因があります。スニペットが短すぎてどれが原因であるかを絞り込むことができません。1 つ目は ReportProgress メソッドで、イベント ハンドラーは UI スレッドで実行されます。頻繁に呼び出すと、UI スレッドが呼び出し要求であふれ、それらの処理に時間がかかりすぎる可能性があります。ペイント要求への応答やユーザー入力の処理など、通常の業務を行うことはもうありません。呼び出しリクエストの処理が完了するとすぐに、ディスパッチされるのを待っている別のリクエストがあるためです。UI スレッドは実際にはフリーズしていません。フリーズしているように見えます。正味の効果は同じです。ワーカーの速度を落とすか、ReportProgress の呼び出し頻度を減らして修正する必要があります。

2 番目の原因は、フリッカーオブジェクトがスレッド セーフではなく、それ自体がスレッド セーフな方法で使用されていることです。ワーカー スレッドから UI スレッドへの呼び出しを自動的にマーシャリングする。これは COM コンポーネントでは非常に一般的であり、この種のマーシャリングは COM のコア機能です。ここでも、UI スレッドは実際にはフリーズしていませんが、写真のアップロードでビジーであるため、ペイントと入力を処理しません。ワーカー スレッドでフリッカーオブジェクトを作成して修正する必要があります。BackgroundWorker ではこれを実行できない可能性が高いため、このようなコンポーネントには、メッセージ ループをポンピングする STA スレッドが必要になることがよくあります。Thread.SetApartmentState() と Application.Run() が必要です。

于 2012-06-30T08:45:21.677 に答える
0

次のようなことをしている場合:

while(worker.IsBusy)
{
}

完了するのを待つと、UI スレッドがループ内で拘束され、バックグラウンド ワーカーが UI スレッドを呼び出してビジー プロパティを安全に設定する必要があるため、デッド ロックが発生してハングします。

于 2012-06-30T08:09:38.560 に答える