3

基本的にサーバーからデータを取得し、GUI にデータを表示する WPF アプリケーションを分析してきました。

このコードは私のものではなく、GUI からの応答が遅いことに関連する問題がアプリケーションにあるため、その問題の原因を突き止めようとしています。

問題が何であるかについての私の考えをあなたと共有したいと思います.

サーバーからデータを取得するために、アプリケーションは 7 つのスレッドを使用しています (これは主にアプリケーション ロジックが原因でこの方法で行われるため、1 つだけでなく 7 つであることにはあまり注意を払わないでください...)。各スレッドは、CreateThreadForTask() というメソッドを呼び出すことによって作成されます。

public void StartAllThreads()
{
    this.CreateThreadForTask(Tasks.Task1);
    this.CreateThreadForTask(Tasks.Task2);
    this.CreateThreadForTask(Tasks.Task3);
    this.CreateThreadForTask(Tasks.Task4);
    this.CreateThreadForTask(Tasks.Task5);
    this.CreateThreadForTask(Tasks.Task6);
    this.CreateThreadForTask(Tasks.Task7);
}

public void CreateThreadForTask(Tasks task)
{
    ... // this part of the code is not important
    
    //! Initialize and start timer
    timer = null;
    timer = new DispatcherTimer();
    timer.Tick += new EventHandler(RunMainSyncForTask);
    timer.Start();  
}

public void RunMainSyncForTask(object s, EventArgs e)
{
    int sec = int.Parse(AppSettings.GetSetting("syncInterval"));
    timer.Interval = new TimeSpan(0, 0, sec);
    
    //threadCaller is a background worker
    threadCaller = InitializeThread();
    threadCaller.DoWork += DoWorkEventHandler(StartSync);
    threadCaller.RunWorkerAsync();
}

コードをデバッグしているときに、すべてのスレッドが DispatcherTimer を使用して作成されていることに気付きました。私が思うに、アプリケーションは 7 つの DispatcherTimer を作成し、タイマーの Tick イベントを RunMainSyncForTask() メソッドにリンクしています。このメソッドは内部でサーバーからデータを取得し、そのデータをローカル データベースに保存するバックグラウンド ワーカーを作成します。

さて、これはMSDNから取られました

DispatcherTimer は、すべての Dispatcher ループの先頭で再評価されます。

タイマーは、時間間隔が発生したときに正確に実行されることは保証されていませんが、時間間隔が発生する前に実行されないことは保証されています。これは、DispatcherTimer 操作が他の操作と同様に Dispatcher キューに置かれるためです。DispatcherTimer 操作が実行されるタイミングは、キュー内の他のジョブとその優先度に依存します。

したがって、これに基づいて、タイマーがティック イベントを実行するたびにアプリケーションがスレッドをスパム送信していると考えられます。これは同時に 7 回実行されます。DispatcherTimer の性質により、これらすべての操作が Dispatcher キューに追加されます。これにより、Dispatcher がビジー状態になるため、GUI の応答が遅くなります。

また、アプリケーションのもう 1 つの問題は、実行時に CPU の約 90 ~ 95% を使用することです。私の仮説が正しければ、これもこの問題の原因である可能性があると思います。

ですから、これについていくつかの内部を共有できれば、私はそれを感謝します.

ありがとう。

4

1 に答える 1

1

クレイジーなスレッド呼び出しの Web を介してビジー待機の形式を設定したため、90 ~ 95% の CPU を取得しています。

このStartSyncロジックを使用してステータス通知を投稿したり、データを GUI に戻したりする場合、多くの困難を乗り越えることになります。.Net 4.0 を使用している場合は、Task Parallel Libraryに切り替えて、フレームワークにすべてを処理させる必要があります。グレースフルキャンセルなどにも対応。

TPL を使用したくない場合は、代わりにWindows Dispatcher(通常の容疑者: Invoke または BeginInvoke を使用) またはSynchronizationContext(非同期でPostと同期的にSend) を個々のタスクに渡して、これらのタスクで使用することをお勧めします。 GUI。

于 2011-03-17T22:40:17.700 に答える