您的位置:首页 > 编程语言 > C#

C# winform问题集

2013-12-21 14:57 274 查看

一 多线程内操作控件问题

//加上这个判断,多线程关闭或窗体关闭,程序退出时不会报控件未创建上调用控件之类的错误

if (zedGraphControl1.IsHandleCreated)

{

//控件方法调用

this.Invoke(new Action(() => zedGraphControl1.AxisChange()));

this.Invoke(new Action(this.zedGraphControl1.Refresh));

}

//更新定标曲线数据源,刷新图

if (label1.IsHandleCreated)

{

//控件属性设置

this.Invoke(new Action<string>((d) => label1.Text = d), i.ToString());

}

二 类型(数据类型溢出问题)

Mhcl0...都是ushort 类型,下面这样调用未出问题,当单个值超过30000时会溢出,因为 Mhcl0* Rhcl1 的积会溢出

double n = Convert.ToDouble(Mhcl0* Rhcl1* 1.0) / (Mhcl1 * Rhcl0));

用这种方式即可避免,因为每个强制转为float,相乘的积以float的范围来check

double n = Convert.ToDouble((Convert.ToSingle(Mhcl0) * Convert.ToSingle (Rhcl1) * 1.0) / (Convert.ToSingle( Mhcl1) *Convert.ToSingle( Rhcl0)));

三 禁用窗体关闭按钮

一种方法是可以在窗体的属性面板将窗体的 ControlBox属性设置为false,或者在窗体的构造函数中这样写:

public Form1()

{

InitializeComponent();

this.ControlBox = false; // 设置不出现关闭按钮

}

不过这样做的话,会连同最小化和最大化按钮都给弄掉了,所以,如果你想只想让关闭按钮不起作用,然后保留最小化、最大化的话,就重写窗体的CreateParams方法:

//禁用窗体的关闭按钮

private const int CP_NOCLOSE_BUTTON = 0x200;

protected override CreateParams CreateParams

{

get

{

CreateParams myCp = base.CreateParams;

myCp.ClassStyle = myCp.ClassStyle | CP_NOCLOSE_BUTTON;

return myCp;

}

}

四 线程关闭问题

1 )改成后台线程就可以了,这样主窗口关闭的时候会自动关闭这些线程。

获得进程的process实例p,使用p.GetThreads获得线程集合。

Process current = Process.GetCurrentProcess();

ProcessThreadCollection allThreads = current.Threads;

ProcessThreadCollection allThreads = current.Threads;

//当前线程

Console.WriteLine("ID:{0}", Thread.CurrentThread.ManagedThreadId);

ThreadPool.GetMaxThreads(out maxWorkerThreads, out portThreads);

ThreadPool.GetAvailableThreads(out workerThreads, out portThreads);

if (maxWorkerThreads - workerThreads == 0)

{

Console.WriteLine("Thread Finished!");

break;

}

2) 关闭创建线程的窗体

this.Close(); 只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),也无法干净地退出;

Application.Exit(); 强制所有消息中止,退出所有的窗体,但是若有托管线程(非主线程),也无法干净地退出;

Application.ExitThread(); 强制中止调用线程上的所有消息,同样面临其它线程无法正确退出的问题;

System.Environment.Exit(0); 这是最彻底的退出方式,不管什么线程都被强制退出,把程序结束的很干净。

3)

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]

public static extern int TerminateThread(int hThread);

foreach (ProcessThread pt in Process.GetCurrentProcess().Threads)

{

TerminateThread(pt.Id);

}

4) 主动杀掉线程

try

{

if (testThread != null)

{

if (testThread.IsAlive)

{

testThread.Abort();

}

testThread = null;

}

}

catch

{ }

五 线程内开启(打开)窗体方式

如果要在线程内开启另一个窗体,当线程运行结束后创建的窗体也会没有了,用如下方式开启新窗体则可以解决该问题

MethodInvoker methodinvoke = new MethodInvoker(ShowSamplingfrm);

BeginInvoke(methodinvoke);

FrmGFSampling frmGFSampling = null;

private void ShowSamplingfrm()

{

if (frmGFSampling != null)

{

frmGFSampling.Show();

}

else

{

frmGFSampling = new FrmGFSampling();

frmGFSampling.Show();



}

}

六 文本框内容始终显示最新内容

在文本框的TextChanged 事件里设置

lblText.SelectionStart = lblText.TextLength;

lblText.ScrollToCaret();



七 **类型初始值设定项引发异常

在实例化一个类或者调用类的静态方法时,如果有静态成员变量初始化失败,则会引发该异常,如果是发现该类型的错误检查下是不是引用了静态类的静态变量(最好是调试),发现多数是因为有某个变量初始化失败了引起的

八 未处理 objectdisposedexception 已关闭 Safe handle 异常

程序在初始化完后不定时会出现这个异常,try catch里也没有捕获到,逐个方法调试也没有发现有问题,但在最后初始化完显示主窗体时则会抛出这个异常,无态下用排除法一个一个方法注释,看受影响的是那个方法,果真发现原来是一个串口初始化的方法引起的,情况是这样的,在这个方法里定义了一个局部变量,初始化一个串口,并打开串口,当这个方法结束时该变量结束了,但串口还在开着,所以会抛出此异常,解决方法定义一个全局的变量来初始化这个串口,或者在初始化完后关掉串口也可以。问题解决!

---end--
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: