线程异常抛出问题
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
private static int i;
private static Thread TestThread;
static void Main(string[] args)
{
TestMain();
Console.ReadLine();
}
private static void Test()
{
int xx = 9;
int yy = 0;
try
{
Console.WriteLine(xx / yy);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
private static void TestMain()
{
for (i = 0; i < 3; i++)
{
try
{
TestThread = new Thread(new ThreadStart(Test));
TestThread.Start();
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
}
}
}
}
在方法Test中,遇到除0错误,我想把错误抛出来,,可是我这样写不行..得怎么改,才能抛出错误! --------------------编程问答-------------------- 顶上去,,求助.. --------------------编程问答-------------------- Main()中添加TestThread。Join() --------------------编程问答--------------------
try
{
TestThread = new Thread(new ThreadStart(Test));
TestThread.Start();
TestThread.Join();
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
按照楼上的添加TestThread.Join(),,运行时还是不行哦,还是卡在除0的错误上. --------------------编程问答-------------------- try
{
TestThread = new Thread(new ThreadStart(Test));
TestThread.Start();
}
catch(Exception ex)
{
Console.WriteLine(ex); 这个地方是得不到异常得。
}
try
{
Console.WriteLine(xx / yy);
}
catch (Exception ex)
{
throw new Exception(ex.Message); 你只能在这个地方把异常处理掉。
}
新创建的线程将引发NullReferenceException异常。当你考虑到每个线程有独立的执行路径的时候,便知道这行为是有道理的,补救方法是在线程处理的方法内加入他们自己的异常处理:
--------------------编程问答-------------------- try
{
..
}
cath (ArithmeticException ex)
{
Console.WriteLine(ex);
}
算术运算引发的特殊异常 --------------------编程问答-------------------- 楼上两位意思是不出抛出异常?
那是不是只能改成下面这样。。在catch里不要加抛出的方法,留空白?
int xx = 9;
int yy = 0;
try
{
Console.WriteLine(xx / yy);
}
catch (Exception)
{
//throw new Exception(ex.Message);
}
--------------------编程问答-------------------- lz是在VS里面跑得吧,直接在外面跑,错误就抛出来了 --------------------编程问答-------------------- 回楼上的
是啊,我是在VS调试的。。 --------------------编程问答-------------------- 那现在大家能否告诉我。。
我应该怎么做。。
因为Test()这个方法是放在类文件里的。。在外层执行这个方法时,我想在遇到错误时,就抛出错误,让上一层调用的可以提示出错误信息内容。。。应该怎么做。。 --------------------编程问答-------------------- dsfasfds --------------------编程问答-------------------- 顶上去求助。。。 --------------------编程问答-------------------- 搜索来的
用事件来捕捉异常,这只是其中一种方法
--------------------编程问答-------------------- 兄弟。都说了啊。 线程有独立的执行路径
form 的代码
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace CatchThreadError
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnTest;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.btnTest = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnTest
//
this.btnTest.Location = new System.Drawing.Point(192, 96);
this.btnTest.Name = "btnTest";
this.btnTest.TabIndex = 0;
this.btnTest.Text = "Test";
this.btnTest.Click += new System.EventHandler(this.btnTest_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(392, 266);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.btnTest});
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void btnTest_Click(object sender, System.EventArgs e)
{
TestDialog td = new TestDialog() ;
try
{
td.ShowDialog() ;
}
catch(Exception exp)
{
MessageBox.Show("all done") ;
}
}
}
}
dialog的代码
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading ;
namespace CatchThreadError
{
/// <summary>
/// TestDialog 的摘要说明。
/// </summary>
public class TestDialog : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnStart;
private System.Windows.Forms.Button btnClose;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public TestDialog()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
private void btnStart_Click(object sender, System.EventArgs e)
{
TestClass testClass = new TestClass() ;
testClass.ThrowException += new ExceptionEventHandler(OnException) ;
Thread thread = new Thread(new ThreadStart(testClass.Run)) ;
thread.Start() ;
thread.Join() ;
}
public void OnException(ExceptionEventArgs e)
{
MessageBox.Show("程序运行出错:" + e.MyException.ToString()) ;
this.Close() ;
}
}//end class
/// <summary>
/// 错误捕捉委托
/// </summary>
public delegate void ExceptionEventHandler(ExceptionEventArgs e) ;
/// <summary>
/// 工作类
/// </summary>
public class TestClass
{
/// <summary>
/// 委托
/// </summary>
public event ExceptionEventHandler ThrowException ;
/// <summary>
/// 委托方法
/// </summary>
/// <param name="e"></param>
protected virtual void OnThrowException(ExceptionEventArgs e)
{
if(ThrowException != null)
{
ThrowException(e) ;
}
}
/// <summary>
/// 工作方法
/// </summary>
public void Run()
{
try
{
for(int i = 0 ; i < 100 ; i ++)
{
Console.WriteLine("执行到:{0}" , i) ;
Thread.Sleep(100) ;
if(i == 50)
{
throw(new Exception("error")) ;
}
}
}
catch(Exception e)
{
ExceptionEventArgs exp = new ExceptionEventArgs() ;
exp.MyException = e ;
OnThrowException(exp) ;
}
}//end method
}//end class
/// <summary>
///
/// </summary>
public class ExceptionEventArgs:EventArgs
{
private Exception m_objMyExcepiton ;
public Exception MyException
{
get
{
return this.m_objMyExcepiton;
}
set
{
this.m_objMyExcepiton = value ;
}
}
}//end class
}//end namespace
你外面得和里面这个不在一个线程里面是不能得到异常得。
所以线程里面得异常需要在线程里面处理。
大家不在同一条路上。 车祸要分开处理。你不能让另外一个路上的易做图来这边。那另外一条路上得车祸又怎么办呢?
在2005里面线程里面得异常不处理得话, 会导致整个应用程序中断运行。
--------------------编程问答--------------------
private static void Test()
{
int xx = 9;
int yy = 0;
Console.WriteLine(xx / yy);
if(YY==0)
{
throw new InvaidNumberInput("除数不能为零");
}
}
--------------------编程问答-------------------- 兄弟。都说了啊。 线程有独立的执行路径
你外面得和里面这个不在一个线程里面是不能得到异常得。
所以线程里面得异常需要在线程里面处理。
大家不在同一条路上。 车祸要分开处理。你不能让另外一个路上的易做图来这边。那另外一条路上得车祸又怎么办呢?
在2005里面线程里面得异常不处理得话, 会导致整个应用程序中断运行。
呵呵,有点抽象。因为Test()方法,是给很多地方调用的。我想出错时就能提示出来。
你的意思是说,在线程里出错,只能在线程里作忽略,而不能把错误信息抛出给上一层,是不是?
或者还有其它什么办法。,你能不能在我的例子里,改好代码直接给我啊? --------------------编程问答-------------------- 一般需要在Test中捕获异常,因为主线程不可能轻易捕捉到这个新线程中的异常。至于抛回主线程,也不是很难。主线程中定义一个ReceiveException(Exception)的方法。新线程一旦遇到异常,就异步调用这个ReceiveException方法,把捕获的异常对象作为参数发回主线程就好了。 --------------------编程问答-------------------- 谢谢楼上的。。不知可否直接在我例子里作修改再给我呢。。
补充:.NET技术 , C#