2011-12-04 10 views
4

巨大なファイルをメモリにロードしていますが、この計算ではアプリケーションがフリーズしています。重い計算でUIがフリーズする

私のコードの問題は何ですか?

public void Drop(DragEventArgs args) 
{ 
    BackgroundWorker worker = new BackgroundWorker(); 
    string fileName = IsSingleTextFile(args); 
    if (fileName == null) return; 
    worker.DoWork += (o, ea) => 
    { 
    try 
    { 
     StreamReader fileToLoad = new StreamReader(fileName); 
     string filecontent = fileToLoad.ReadToEnd(); 
     fileToLoad.Close(); 
     // providing the information to the UI thread 

     Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, 
     new Action(() => SfmLogFile = filecontent)); 
    } 
    catch (Exception) 
    { 
     throw; 
    } 
    }; 

    worker.RunWorkerCompleted += (o, ea) => 
    { 
    args.Handled = true; 
    IsBusy = false; 
    }; 

    // Mark the event as handled, so TextBox's native Drop handler is not called. 

    IsBusy = true; 
    worker.RunWorkerAsync(); 

} 
+0

から成り、「//は、UIスレッドへの情報提供」とは何ですか? – Tigran

+0

SfmLogFileとは何ですか?なぜあなたはDropイベントハンドラの本体の代わりにRunWorkerCompletedにargs.Handledを設定しますか? –

+0

@Tigran、SfmLogFile = filecontent私は自分のUIがバインドされている文字列を更新しています。 –

答えて

2

私はこのような何かにあなたのサンプルを変換したい:

public void Drop(DragEventArgs args) 
{ 
    string fileName = IsSingleTextFile(args); 
    if (fileName == null) return; 
    // It is better to create worker after check for file name. 
    BackgroundWorker worker = new BackgroundWorker(); 
    worker.DoWork += (o, ea) => 
    { 
    try 
    { 
     string filecontent = ReadAllText(fileName);  
     ea.Result = fileContent; 
    } 
    catch (Exception) 
    { 
     throw; 
    } 
    }; 

    worker.RunWorkerCompleted += (o, ea) => 
    { 
    var fileContent = ea.Result as string; 
    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, 
     new Action(() => SfmLogFile = filecontent)); 

    // if IsBusy propery is not on the UI thread, then you may leave it here 
    // otherwise it should be set using the dispatcher too. 
    IsBusy = false; 
    }; 

    IsBusy = true; 
    worker.RunWorkerAsync(); 
    // Mark the event as handled, so TextBox's native Drop handler is not called.  
    args.Handled = true; 
} 
+0

私は長さ20メガのUI文字列を使用していますので、遅いこともあります。 –

1

私はそれはあなたの問題の原因かどうかわからないが、あなたは、バックグラウンドワーカーのためのコールバックでargs.Handledを設定しているので、ドロップイベントハンドラが戻った後にそれが呼び出されます。あまりにも遅く設定されているので、望みの効果が得られませんし、イベントハンドリングで何か混乱するかもしれません。

関連する問題