2013-07-25 29 views
9

Tôi nhận được hiệu suất kém khi định dạng văn bản trong một rtb:định dạng Slow của RichTextBox

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition/> 
    </Grid.RowDefinitions> 
    <StackPanel Orientation="Horizontal"> 
     <Button Click="ApplyFormatClick">ApplyFormat</Button> 
     <TextBlock x:Name="Time"/> 
    </StackPanel> 

    <RichTextBox x:Name="Rtb" Grid.Row="1"> 
     <RichTextBox.Document> 
      <FlowDocument> 
       <Paragraph> 
        <Run> 
         Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum 
        </Run> 
       </Paragraph> 
      </FlowDocument> 
     </RichTextBox.Document> 
    </RichTextBox> 
</Grid> 

Mã đằng sau:

private readonly SolidColorBrush _blueBrush = Brushes.Blue; 
private void ApplyFormatClick(object sender, RoutedEventArgs e) 
{ 
    Stopwatch stopwatch = Stopwatch.StartNew(); 
    FlowDocument doc = Rtb.Document; 
    TextRange range = new TextRange(doc.ContentStart, doc.ContentEnd); 
    range.ClearAllProperties(); 
    int i = 0; 
    while (true) 
    { 
     TextPointer p1 = range.Start.GetPositionAtOffset(i); 
     i++; 
     TextPointer p2 = range.Start.GetPositionAtOffset(i); 
     if (p2 == null) 
      break; 
     TextRange tempRange = new TextRange(p1, p2); 
     tempRange.ApplyPropertyValue(TextElement.ForegroundProperty, _blueBrush); 
     tempRange.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold); 
     i++; 
    } 
    Time.Text = "Formatting took: " + stopwatch.ElapsedMilliseconds + " ms, number of characters: " + range.Text.Length; 
} 

Áp dụng định dạng có trên một giây và khi profiling nó trở thành thủ phạm là:

tempRange.ApplyPropertyValue(TextElement.ForegroundProperty, _blueBrush); 
tempRange.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold); 

Kết quả hồ sơ khá rõ ràng đối với tôi.

Tôi chưa bao giờ sử dụng FlowDocumentRichTextBox trước đây vì vậy tôi có thể làm điều này rất sai.

Kết quả cuối cùng có nghĩa là tương tự như VS tìm thay thế sẽ làm nổi bật các kết quả phù hợp trong văn bản dựa trên regex có thể chỉnh sửa.

Điều gì có thể được thực hiện khác để tăng tốc độ này? (Sample on Github)

Trả lời

8

Đề xuất sẽ được tự xây dựng FlowDocument của bạn với các định dạng mới (you can check the MSDN Magazine August 2007: WPF Flexible Content Display With Flow Documents; hoặc bài viết MSDN gần đây nhất Flow Document Overview), mà sẽ cải thiện hiệu suất đáng kể, ví dụ sử dụng ví dụ của bạn nếu làm điều đó bằng tay như dưới đây, trên máy tính của tôi nó sẽ nhận được kết quả trong 52 ms, nơi như sử dụng ApplyPropertyValue sẽ mất 1266 ms:

private readonly SolidColorBrush _blueBrush = Brushes.Blue; 

private void ApplyFormatClick(object sender, RoutedEventArgs e) 
{ 
    Stopwatch stopwatch = Stopwatch.StartNew(); 
    FlowDocument doc = Rtb.Document; 
    TextRange range = new TextRange(doc.ContentStart, doc.ContentEnd); 
    Paragraph para = new Paragraph(); 
    string rangetem = range.Text; 
    range.ClearAllProperties(); 

    for(int i=0; i<rangetem.Count();i+=2) 
    { 
     Span s = new Span() { Foreground = _blueBrush }; 
     Bold b = new Bold(); 
     s.Inlines.Add(rangetem[i].ToString()); 
     b.Inlines.Add(s); 
     para.Inlines.Add(b); 
     if(i+1<rangetem.Count()) 
     { 
      para.Inlines.Add(rangetem[i + 1].ToString()); 
     } 
    } 
    doc.Blocks.Clear(); 
    doc.Blocks.Add(para); 

    Time.Text = "Formatting took: " + stopwatch.ElapsedMilliseconds + " ms, number of characters: " + range.Text.Length; 
} 
+0

có một Impro kịch tính vement thực sự, xuống đến 38ms bây giờ trên một crap-top. –

+0

@ Bolu Bạn vừa mới cứu mạng tôi. Tôi đã có một đoạn mã với 'ApplyPropertyValue' mất tới 5 giây để hoàn thành. Với giải pháp của bạn nó là siêu nhanh. Cảm ơn bạn rất nhiều. Bạn có biết tại sao có vấn đề hiệu suất với chức năng này? – Chostakovitch

+0

Liên kết chỉ trỏ đến tổng quan về các sự cố MSDN ngay bây giờ. – Lennart

5

Nếu chức năng lại là không cần thiết từ RichTextBox bạn có thể bóp thêm một chút hiệu suất bằng cách thiết lập IsUndoEnabled false

<RichTextBox IsUndoEnabled="False"> 
1

Bạn có thể cải thiện đáng kể hiệu suất văn bản Formating bằng cách sử dụng các phương pháp sau:

rtb.BeginChange(); 

/// Your formating logic 

rtb.EndChange();