减少C#窗体控件中的时间。设置#文本(字符串)函数

减少C#窗体控件中的时间。设置#文本(字符串)函数,c#,winforms,timer,C#,Winforms,Timer,希望能得到一个快速的答案(这对我来说似乎很好) 我刚刚用VS2010在我的应用程序上运行了一次性能分析,结果表明我花了大约20%的时间在控件。set_Text(string)函数上,因为我在我的应用程序的很多地方更新标签 该窗口有一个timer对象(Forms timer,而不是Threading timer),它有一个timer1\u Tick回调,该回调每Tick更新一个标签(以产生秒表效果),每秒更新大约15个标签 除了增加更新间隔外,是否有人对如何减少表单上的文本更新时间提出了快速建议?

希望能得到一个快速的答案(这对我来说似乎很好)

我刚刚用VS2010在我的应用程序上运行了一次性能分析,结果表明我花了大约20%的时间在
控件。set_Text(string)
函数上,因为我在我的应用程序的很多地方更新标签

该窗口有一个timer对象(Forms timer,而不是Threading timer),它有一个
timer1\u Tick
回调,该回调每Tick更新一个标签(以产生秒表效果),每秒更新大约15个标签


除了增加更新间隔外,是否有人对如何减少表单上的文本更新时间提出了快速建议?我还应该使用其他结构或函数吗?

我自己也遇到了这个问题,最后创建了自己的简单标签控件

Net的标签控件是一个异常复杂的庞然大物,因此速度比我们想象的要慢

您可以创建一个继承
控件的类,在构造函数中调用
SetStyle
,使其成为双缓冲区并由用户绘制,然后重写
OnPaint
方法来调用
e.Graphics.DrawString
并绘制
Text
属性。
最后,重写
Text
TextChanged
并调用
Invalidate

只要不需要自动调整大小,这将大大快于标准标签控件

以下是我的实现:(目前正在生产中使用)

///一个简单但极快的控件。
///信不信由你,常规标签速度不够快,甚至双缓冲。
类FastLabel:控件{
公共快速标签(){
设置样式(ControlStyles.AllPaintingInWmPaint
|ControlStyles.CacheText
|ControlStyles.OptimizedDubleBuffer
|ControlStyles.ResizerDraw
|ControlStyles.UserPaint,true);
}
受保护的重写void OnTextChanged(EventArgs e){base.OnTextChanged(e);Invalidate();}
受保护的重写void OnFontChanged(EventArgs e){base.OnFontChanged(e);Invalidate();}
静态只读StringFormat格式=新StringFormat{
对齐=StringAlignment.Center,
LineAlignment=StringAlignment.Center
};
受保护的覆盖无效OnPaint(PaintEventArgs e){
e、 Graphics.DrawString(文本、字体、SystemBrush.ControlText、ClientRectangle、格式);
}
}

如果您不想居中,可以去掉或更改
StringFormat

那么,指定Text属性大约需要0.6纳秒。这是昂贵的副作用。您可能已经为标签启用了AutoSize属性。因此,它需要创建字体句柄,在临时设备上下文中呈现文本,测量结果字符串,考虑到TrueType暗示的副作用,TrueType暗示人为拉伸字母形状,使其与监视器上的像素一致,还需要调整修改后的ABC度量以使ClearType正常工作。然后告诉本机Windows控件它需要更改其窗口大小。这将为标签以及作为标签控件父控件的容器控件生成绘制事件。它再一次经历了同样的程序,现在实际绘制像素。当启用Aero时,会更改内存设备上下文中的字节,该字节需要被Blit到实际更新视频内存的视频设备驱动程序,以便用户可以看到结果

是的,那需要时间


通过编写自己的代码而不是Windows窗体为您编写代码来加快速度。替代OnPaint事件,使用TextRender.DrawText绘制标签。在那里快速获胜,速度轻松提高50倍。减去设计师的点击方便。

这与我所需要的非常接近,但我注意到了两件事——我的字体现在看起来很有趣,所有标签都需要调整大小以适应这种变化。另外,现在我花了30%的时间在DrawString函数上,这似乎并没有加快表单的响应速度。有什么想法吗?我不知道为什么会这样。字体到底是什么样子的?字母和字母间距看起来稍微宽一点-在这两种情况下都是MS Sans Serif 8.25 pt,但FastLabel只是更宽一点。我很快尝试了使用这种方法,但我猜我需要做的不仅仅是创建一个覆盖OnPaint方法的简单
类MyFastLabel:Label
?仅使用该函数和TextRenderer.DrawText()方法,任何MyFastLabel都不会显示。还应该包括什么?我不认为继承标签会提供任何速度优势,除了双缓冲。@slaks:你完全没有抓住要点。一张表格或一个小组可以画出任何标签可以画的东西。我是指他的评论。
///<summary>A simple but extremely fast control.</summary>
///<remarks>Believe it or not, a regular label isn't fast enough, even double-buffered.</remarks>
class FastLabel : Control {
    public FastLabel() {
        SetStyle(ControlStyles.AllPaintingInWmPaint
               | ControlStyles.CacheText
               | ControlStyles.OptimizedDoubleBuffer
               | ControlStyles.ResizeRedraw
               | ControlStyles.UserPaint, true);
    }
    protected override void OnTextChanged(EventArgs e) { base.OnTextChanged(e); Invalidate(); }
    protected override void OnFontChanged(EventArgs e) { base.OnFontChanged(e); Invalidate(); }

    static readonly StringFormat format = new StringFormat {
        Alignment = StringAlignment.Center,
        LineAlignment = StringAlignment.Center
    };
    protected override void OnPaint(PaintEventArgs e) {
        e.Graphics.DrawString(Text, Font, SystemBrushes.ControlText, ClientRectangle, format);
    }
}