这段时间做WinForm 有些地方加载时间太长给人的感觉很不爽,无奈仿照web的loading及Ajax异步加载。
刚开始用多线程,结果未遂,提示线程安全(不是创建控件的线程无法访问)
然后用异步委托,虽然实现了异步加载但是代码一点都不好看,偶然间发现有位前辈用Application.DoEvents(),查询发现能实现同样的效果只是不能放到线程中,当然效果是一样的。
现在把代码和测试效果贴上:
形式1:正常的10000次循环,界面卡死知道循环10000次然后显示执行结果。一般1300左右,最长1900左右。
View Code
Stopwatch stw = new Stopwatch();
stw.Start();
for (int i = 0; i < 10000; i++)
{
label5.Text = i.ToString();
}
stw.Stop();
button5.Text = stw.ElapsedMilliseconds.ToString();
形式2:界面正常每一次都让主线程继续 label1 动态显示。--正常显示,当运行软件多时用时7000毫秒,一般在6500左右,最低到达6300左右。
Stopwatch stw = new Stopwatch();
stw.Start();
for (int i = 0; i < 10000; i++)
{
label1.Text = i.ToString();
Application.DoEvents();
}
stw.Stop();
button1.Text = stw.ElapsedMilliseconds.ToString();
形式3:用线程池线程执行调用主线程异步显示执行结果。--极少几率出现极短暂停顿,打开好多软件,好多网页,还未完全打开是这中形式改用label2.Invoke用时10000毫秒,一般6500毫秒左右,最低5900左右,应该是很稳定的一种。
ThreadPool.QueueUserWorkItem(new WaitCallback((a) =>
{
Stopwatch stw = new Stopwatch();
stw.Start();
for (int i = 0; i < 10000; i++)
{
this.Invoke(new MethodInvoker(() =>
{
label2.Text = i.ToString();
}));
}
stw.Stop();
this.Invoke(new MethodInvoker(() =>
{
button2.Text = stw.ElapsedMilliseconds.ToString();
}));
}));
button2.Text = "ThreadStart";
形式4:用新线程执行调用主线程异步显示执行结果。--基本不会卡壳在正常情况下速度最慢的7000毫秒左右
Thread th = new Thread(new ThreadStart(() =>
{
Stopwatch stw = new Stopwatch();
stw.Start();
for (int i = 0; i < 10000; i++)
{
label4.Invoke(new MethodInvoker(() =>
{
label4.Text = i.ToString();
}));
}
stw.Stop();
this.Invoke(new MethodInvoker(() =>
{
button4.Text = stw.ElapsedMilliseconds.ToString();
}));
}));
th.Start();
形式5:不用线程但是动态的调用创建控件的句柄执行委托。--来不急显示就到下次循环了一般比形式1稍多点时间。
Stopwatch stw = new Stopwatch();
stw.Start();
for (int i = 0; i < 10000; i++)
{
label6.Invoke(new MethodInvoker(() =>
{
label6.Text = i.ToString();
}));
}
stw.Stop();
this.Invoke(new MethodInvoker(() =>
{
button6.Text = stw.ElapsedMilliseconds.ToString();
}));
button6.Text = "ThreadStart";
呵呵,明天测试下委托和匿名委托的性能差异,还有List<T>.ForEach 和foreach 的差异。
话说今天看一视频说vs2010,看到里面好多东西用起来简单多了,不过我怎么感觉不利于程序员的发展。
比如重载都穿马甲了。
int GetModel(int id=11,string name="admin",bool state=false)
{
return 0;
}
调用居然可以 GetModel(),GetModel(name="text"),GetModel(state=true),GetModel(id=1,state=false)
太神奇了,不过好像是那个脚本框架有点像。
本人是新手在文章中的诸多错误和不足之处还望大家指出,非常感谢。
交流使人强大。
由于项目中需要对文本操作就用了RichTextBox,可是RichTextBox不能添加想word一样的超链接(也许可以,本人未发现),添加超链接会变成文本+<连接地址>的形式,无论是后台导入Rtf文档还是从word里粘贴出来都会出现那种现象。
只找到两种不能完全解决的方法,现在大家帮忙看看有没有完美的解决方法。
前提都是要设置RichTextBox的DetectUrls为True
True 粘贴或是别的手段加入的超链接都会是真正的超链接(虽然不加事件点击没反应)
false 粘贴或是别的手段加入的超链接看起来是超链接其实没有超链接属性(加了连接事件也没反应)
方法1:给RichTextBox 加LinkClicked 事件
View Code
void richTextBox1_LinkClicked(object sender, LinkClickedEventArgs e)
{
MessageBox.Show(e.LinkText);
//"链接< http://www.baidu.com >" sender 是 整个下划线部分,e是后面<>里的部分//这里可以在浏览器中打开,也可以自己的窗体打开
}
这样看起来和word不一样客户有意见,除非就是把所有链接的文字和链接地址存放到字典,可是文字也不能设置点击事件,郁闷中。。。
方法2:给RichTextBox 加LinkLabel控件
View Code
LinkLabel lb = new LinkLabel();
lb.Text = "超链接";
object obj = new object();
obj = "www.baidu.com";
lb.Links.Add(new LinkLabel.Link(0, 3, obj));
lb.LinkClicked += new LinkLabelLinkClickedEventHandler(lb_LinkClicked);
richTextBox1.Controls.Add(lb);
这样LinkLabel 其实就是控件不仅会占用地方(看起来一片)而且不能编辑,感觉很不爽。。。
难道超链接没有一个完美的解决方案么?(看起来和word里一样,用起来和word里也要一样至少表面上要这样)。
希望对有需要的人一点帮助,如果有完美解决方法希望指点一二。
最近做的Winform项目中需要一个文本编辑的地方,其中有字体样式选项刚开始是加载本机全部的字体,
后来发现有些字体根据名称没办法实例化。然后就在加载的时候就利用实例化异常控制程序,但是这种通过异常来控制程序觉得很别扭,不知道哪位对这个Font比较熟悉给点建议。
View Code
InstalledFontCollection fc = new InstalledFontCollection();
foreach (FontFamily font in fc.Families)
{
try
{
new Font(font.Name, 10f);
fontComboBox.Items.Add(font.Name);
}
catch (Exception ex)
{
LogCat.LogCat.Instance().AddException(ex);
}
}
if (fontComboBox.Items.Count > 0)
{
fontComboBox.SelectedIndex = 0;
}
实例化的时候不给FontStyle参数默认就是Regular,但有些字体本身就不是Regular比如:
Aharoni , Berlin Sans FB Demi, Brush Script MT, Harlow Solid Italic, Magneto, Monotype Corsiva, Palace Script MT, Vivaldi


