2011-07-14 12 views
3

データベースにRTF形式で保存されたテキストの量を平文に変更する必要があります。私は方法described in this MSDN articleを使用していますが、私はそれが私のコードではなく、.NETフレームワーク自体ではないと思います。rtfをプレーンテキストに変換するスピードアップ

私は、それは完全に自己完結することと何にもブロックしてはならない以下の機能

//convert RTF text to plain text 
    public static string RtfTextToPlainText(string FormatObject) 
    { 
     System.Windows.Forms.RichTextBox rtfBox = new System.Windows.Forms.RichTextBox(); 
     rtfBox.Rtf = FormatObject; 
     FormatObject = rtfBox.Text; //This is line 494 for later reference for the stack traces. 
     rtfBox.Dispose(); 

     return FormatObject; 
    } 

を持っています。私がやっているプロジェクトには処理が必要な数百万のレコードがありますので、私はバッチで作業を分割し、並列処理を行うタスクを使用しています。それはまだかなり遅いので私はコードに侵入し、これを発見した。ここで

enter image description here

タスク2は、上のタスク4にブロックしているのはなぜここに待ちタスク

[In a sleep, wait, or join] 
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.CreateHandle(System.Windows.Forms.CreateParams cp) + 0x242 bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.CreateHandle() + 0x2b2 bytes 
System.Windows.Forms.dll!System.Windows.Forms.TextBoxBase.CreateHandle() + 0x54 bytes 
System.Windows.Forms.dll!System.Windows.Forms.RichTextBox.Rtf.set(string value) + 0x68 bytes  
>CvtCore.dll!CvtCore.StandardFunctions.Str.RtfTextToPlainText(object Expression) Line 494 C# 

との呼び出しスタックは、スレッドのコールスタック816

[Managed to Native Transition] 
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x9e bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.WmWindowPosChanged(ref System.Windows.Forms.Message m) + 0x39 bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x51b bytes 
System.Windows.Forms.dll!System.Windows.Forms.RichTextBox.WndProc(ref System.Windows.Forms.Message m) + 0x5c bytes 
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x15e bytes  
[Native to Managed Transition] 
[Managed to Native Transition] 
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x9e bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.WmCreate(ref System.Windows.Forms.Message m) + 0x1c bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x50b bytes 
System.Windows.Forms.dll!System.Windows.Forms.RichTextBox.WndProc(ref System.Windows.Forms.Message m) + 0x5c bytes 
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x15e bytes  
[Native to Managed Transition] 
[Managed to Native Transition] 
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.CreateHandle(System.Windows.Forms.CreateParams cp) + 0x44c bytes 
System.Windows.Forms.dll!System.Windows.Forms.Control.CreateHandle() + 0x2b2 bytes 
System.Windows.Forms.dll!System.Windows.Forms.TextBoxBase.CreateHandle() + 0x54 bytes 
System.Windows.Forms.dll!System.Windows.Forms.RichTextBox.Rtf.set(string value) + 0x68 bytes  
>CvtCore.dll!CvtCore.StandardFunctions.Str.RtfTextToPlainText(object Expression) Line 494 C# 

です両方とも完全に独立していてはいけませんか?


NOTE

リリースモードでは、私はデバッグモードで発生する同じものを得るために、正しい時間に一時停止を打つように見えることはできませんが、私はこれらのスタックトレースとスクリーンショットをつかみました。これが私の遅さの原因かもしれませんか?プロファイラは、私のプログラムは `System.Windows.Forms.RichTextBox.set_Rtf(string)(行494で呼び出されるサブ関数です)に時間の83.2%を費やしています。

このストライピング処理のスピードを上げるための提案rtfの書式設定を大幅に高く評価します。


P.S.

私は現在、スレッドごとに、関数が呼び出されるたびに新しいスレッドを作成するのではなく、処理されないテキストボックスを持つように書き直しています。私がそれをした後の詳細と。


UPDATE

私は私自身の問題(以下答える参照)を解決しますが、ここで私はそれがに、とプロデューサ/コンシューマモデルを使用しているタスク

//create start consumer threads 
for (int i = 0; i < ThreadsPreProducer; i++) 
{ 
    //create worked and thread 
    WorkerObject NewWorkerObject = new WorkerObject(colSource, FormatObjectEvent, UpdateModule); 
    Task WorkerTask = new Task(NewWorkerObject.DoWork); 
    WorkerTasks.Add(WorkerTask); 
    WorkerTask.Start(); 
} 


//create/start producer thread 
ProducerObject NewProducerObject = new ProducerObject(colSource, SourceQuery, ConnectionString, PreProcessor, UpdateModule, RowNameIndex); 
Task ProducerTask = new Task(NewProducerObject.DoWork); 
WorkerTasks.Add(ProducerTask); 
ProducerTask.Start(); 


//block while producer runs 
ProducerTask.Wait(); 

//create post producer threads 
for (int i = 0; i < ThreadsPostProducer; i++) 
{ 
    //create worked and thread 
    WorkerObject NewWorkerObject = new WorkerObject(colSource, FormatObjectEvent, UpdateModule); 
    Task WorkerTask = new Task(NewWorkerObject.DoWork); 
    WorkerTasks.Add(WorkerTask); 
    WorkerTask.Start(); 
} 

//block until all tasks are done 
Task.WaitAll(WorkerTasks.ToArray()); 

を開始した方法です私の場合、1人のプロデューサーと4人の消費者(システムリソースがプロデューサーから解放された後に作業をスピードアップするために、プロデューサーが開始されてから2時間が開始されます)。

+0

コードを完全に理解するために、タスクの作成方法を投稿できますか? –

+0

@Ramhound私はどのようにタスクを開始するのかを示すために更新しましたが、rtfボックススレッドをローカルにすることで問題を解決しました。 –

答えて

4

static ThreadLocal<RichTextBox> rtfBox = new ThreadLocal<RichTextBox>(() => new RichTextBox()); 
//convert RTF text to plain text 
public static string RtfTextToPlainText(string FormatObject) 
{ 
    rtfBox.Value.Rtf = FormatObject; 
    FormatObject = rtfBox.Value.Text; 
    rtfBox.Value.Clear(); 

    return FormatObject; 
} 

に機能を変更するには、数秒、数分から私の実行時間を変更しました。

オブジェクトは、プログラムの全期間にわたって使用されるため、処分しません。

+0

よろしくお願いします! うまくいけばうれしいです。 +1自分の質問への回答を投稿して、他の人に役立つようにします。 –

関連する問題