1

やりたいこと: WPF(c#)で Web サービス DLL を使用しています。SmsSenderDLL には、私のコードでクラスとして表示できる Web サービスが含まれています。このクラスの各メソッドを呼び出すには時間がかかるため、そのメソッドを他のスレッドで実行する必要があります。

私がすること: DataView オブジェクト (メソッドからの「戻り値」) を DataGrid の ItemsSource に設定します。だから私は使用しますDispatcher.BeginInvoke()

私の問題: 私の問題はDispatcher.BeginInvoke()、別のスレッドで実行してもプログラムをフリーズさせることができることです。フリーズせずにメソッドを呼び出したい。タイムアウトを定義することは可能ですか?

アップデート1:

時間のかかる方法から DataGrid に DataView を設定するにはどうすればよいですか?

私のコード:

Action action = () =>
{
    SmsSender sms = new SmsSender();

    dgUser1.ItemsSource = sms.GetAllInboxMessagesDataSet().Tables[0].DefaultView;
};

dgUser1.Dispatcher.BeginInvoke(action);

前もって感謝します

4

2 に答える 2

2

簡単だ。UI スレッドでブロッキング I/O を実行しないでください。

SmsSender sms = new SmsSender();
DataView result = sms.GetAllInboxMessagesDataSet().Tables[0].DefaultView
Action action = () =>
{
    dgUser1.ItemsSource = result;
};
dgUser1.Dispatcher.BeginInvoke(action);

ただし、これは実際には WPF アプリを作成する方法ではありません。このパターンは、WinForms のようなパターンを使用して行われます。本当にDataBindingを使用する必要があります。

データバインディングは、すべてのDispatcher呼び出しを処理します。

于 2013-11-02T22:36:09.193 に答える
1

Dispatcher.BeginInvokeUIスレッドでデリゲートを実行し、ディスパッチャーに完全なアクションを配置したため、UIスレッドで実行され、UIハングの問題が発生します。

時間のかかる操作をバックグラウンド スレッドに委譲し、UI 呼び出しを UI スレッドにディスパッチする方法は多数あります。

簡単な例は、を使用することBackgroundWorkerです。非 UI のものをDoWorkイベント ハンドラーにRunWorkerCompleted配置し、UI スレッドでのみ呼び出されるハンドラーに UI 操作を配置するため、UI ディスパッチャーへの呼び出しをディスパッチする必要があります。

小さなサンプル -

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork+=new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted +=
        new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
   dgUser1.ItemsSource = (DataView)e.Result;
}        

void worker_DoWork(object sender, DoWorkEventArgs e)
{
   SmsSender sms = new SmsSender();
   e.Result = sms.GetAllInboxMessagesDataSet().Tables[0].DefaultView;
}
于 2013-11-03T09:08:34.717 に答える