现在的位置: 首页 > 综合 > 正文

处理异常和错误

2012年03月13日 ⁄ 综合 ⁄ 共 9320字 ⁄ 字号 评论关闭

处理异常和错误>

if语句能检查错误,但必须在运行时。try/catch语句能在编译时检查异常。

 

处理异常和错误>finally块的用途

当打开文件,操作发生错误,虽然捕捉到异常,但资源没被释放。所以finally块可用来释放资源或其它。

代码
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace FinallyDemo
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
const string filePath = @"C:\FinallyDemo.txt";
            FileStream fs
=null;
            
try
            {
                Console.WriteLine(
"开始执行文件的比较操作");
                fs 
= new FileStream(filePath, FileMode.CreateNew, FileAccess.ReadWrite);
                
byte[] bytes = Encoding.Default.GetBytes("这是一个字符串,将插入到文本文件");
                
//向流中写入指定的字节数组
                fs.Write(bytes,0,bytes.Length);
                
//将缓冲区的内容存储到媒介并清除缓冲区。
                fs.Flush();
                
//将流指针移到开头。
                fs.Seek(0, SeekOrigin.Begin);
                
byte[] bytes2 = new byte[bytes.Length];
                
//
                fs.Read(bytes2, 0, bytes.Length);
                
string str = Encoding.Default.GetString(bytes2);
                Console.WriteLine(
"从文件中读出的字符串为" + Environment.NewLine+str);
            }
            
catch (IOException ex)                
            {
                Console.WriteLine(
"发生了文件处理的错误!" + ex.Message);
            }
            
finally
            {
                Console.WriteLine(
"不论是否发生异常,都会执行finally到这里");
                
if (fs != null)
                {
                    fs.Close();
                }
                Console.ReadLine();
            }
        }
    }
}

处理异常和错误>预定义异常的类

描述:一个总BOSS异常类,引领两个帮派,一个是CLR自己定义好的异常类,另一个便是用户自定义的异常类。异常类嘛,总有些属性,这些属性提供了异常代码的位置,异常的描述信息啊等等。

所有异常类的基类是System.Exception

·SystemException派生的预定义CLR异常类

·ApplicationException派生的用户自定义的应用程序异常类

你可以查看下System.Exception的属性列表。

 

一个例子:RunMethod调用Method2,Method2调用Method1。Method1抛出一个异常,Method2捕获异常,并将Method1的异常传递给RunMethod, RunMethod调用Exception类的属性,显示异常信息。

显示异常信息
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections;

namespace ExceptionInfos
{
    
class Program
    {
        
static void Main(string[] args)
        {
            Console.WriteLine(
"显示额外的信息的结果为:");
            Console.WriteLine();
            RunMethod(
true);
            Console.WriteLine(
"不显示额外的信息的结果为:");
            Console.WriteLine();
            RunMethod(
false);
            Console.ReadLine();
        }
        
/// <summary>
        
/// 显示当前异常和前一个异常的Exception属性信息。
        
/// </summary>
        
/// <param name="displayDetails"></param>
        static void RunMethod(bool displayDetails)
        {
            
try
            {
                Method2();
            }
            
catch (Exception ex)
            {
                Console.WriteLine(
"当前的异常Message属性值为:{0}", ex.Message);
                Console.WriteLine(
"内部异常的Message属性值为:{0}", ex.InnerException.Message);
                Console.WriteLine(
"当前异常的Source属性值为:{0}", ex.Source);
                Console.WriteLine(
"内部异常的Source属性值为:{0}", ex.InnerException.Source);
                Console.WriteLine(
"当前异常StackTrace属性值为:{0}", ex.StackTrace);
                Console.WriteLine(
"内部异常的StackTrace属性值为:{0}", ex.InnerException.StackTrace);
                Console.WriteLine(
"当前异常TargetSite属性值为:{0}", ex.TargetSite);
                Console.WriteLine(
"内部异常的TargetSite属性值为:{0}", ex.InnerException.TargetSite);
                Console.WriteLine(
"当前异常HelpLink属性值为:{0}", ex.HelpLink);
                Console.WriteLine(
"内部异常的HelpLink属性值为:{0}", ex.InnerException.HelpLink);
            
if (displayDetails)
            {
                
if (ex.InnerException.Data != null)
                {
                    Console.WriteLine(
"额外的异常信息是:");
                    
foreach (DictionaryEntry de in ex.InnerException.Data)
                    {
                        Console.WriteLine(
"键是:{0},值为{1}", de.Key, de.Value);
                    }
                } 
            }
            }
        }
        
/// <summary>
        
/// 为Exception对象设置值,并直接抛出异常。
        
/// </summary>
        static void Method1()
        {
            Exception ex 
= new Exception("这是原始异常消息");

                string s = "来自Method1的信息";
                
int i = 100;
                DateTime dt 
= DateTime.Now;
                ex.Data.Add(
"方法信息", s);
                ex.Data[
"整数值"= i;
                ex.Data[
"时间值"= dt;
                
throw ex;
        }
        
/// <summary>
        
/// 为内部异常的Data属性添加更多的信息。
        
/// </summary>
        static void Method2()
        {
            
try
            {
                Method1();
            }
            
catch (Exception ex)
            {
                Exception e 
= new Exception("这是来自Method2的异常信息", ex);
                e.InnerException.Data[
"附件信息"= "来自Method2的信息";
                e.InnerException.Data.Add(
"更多信息""来自Method2的更多信息");
                
throw e;
            }
        }
    }
}

处理异常和错误>处理和传递异常

方法A,抛出一个异常A1,方法B,调用A,并且也跑出一个异常B1.如果希望在抛出B1的同时,也传递方法A抛出的异常A1,那么,需要将A1作为一个异常参数传递给B1,这样,跑出B1是,也抛出了A1.

传递异常
using System;
using System.Collections.Generic;
using System.Text;

namespace InnerException
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
try
            {
                A2();
            }
            
catch (Exception ex)
            {
                Console.WriteLine(
"捕获的异常消息:{0}", ex.Message);
                Console.WriteLine(
"捕获的异常所传递的异常的消息:{0}", ex.InnerException.Message);
                Console.ReadLine();
            }
        }
        
//A1直接抛出一个异常
        static void A1()
        {            
            Exception ex 
= new Exception("这是来自A1的异常消息");            
            
throw ex;
        }
        
//A2调用A1,并将A1抛出的异常保存到InnerException中。
        static void A2()
        {
            
try
            {
                A1();
            }
            
catch(Exception e)
            {
                Exception ex 
= new Exception("这是来自A2的异常消息",e);
                
throw ex;
            }
        }
    }
}

 

处理异常和错误>从异常中恢复

正在对两个文件同时执行写操作,对第一个文件的写操作已经完成,执行到对第二个文件的写操作时,抛出了异常。假设程序要求两个文件必须全部写入成功,只要有一个文件的写入失败,就应该回滚对第一个文件的写入。

从异常中恢复
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace RollbackException
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
try
            {
                WriteFile();
            }
            
catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
        
/// <summary>
        
/// 异常恢复的示例,假定有两个文件,只要有一个写入失败,就全部回滚。
        
/// </summary>
        static void WriteFile()
        { 
            
const string filePath1=@"C:\RoolbackException1.txt";
            
const string filePath2=@"C:\RoolbackException2.txt";
            FileStream fs 
= null;
            FileStream fs1 
= null;
            
long fsPosition = 0;
            
long fs1Position = 0;
            
try
            { 
                
string str = "这是需要被写入到两个文件中的字符串"
                
byte[] bytes = Encoding.Default.GetBytes(str.ToCharArray());
                fs 
= new FileStream(filePath1, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                
//先将流位置移到文件尾部
                fs.Seek(0, SeekOrigin.End);
                
//获取Position,以用于恢复
                fsPosition = fs.Position;
                
//写入指定的字节数组
                fs.Write(bytes, 0, bytes.Length);
                
//写入磁盘清除缓冲区
                fs.Flush();
                fs1 
= new FileStream(filePath2, FileMode.CreateNew, FileAccess.ReadWrite);
                fs1.Seek(
0, SeekOrigin.End);
                fs1Position 
= fs1.Position;
                fs1.Write(bytes, 
0, bytes.Length);
                fs1.Flush();
            }
            
//catch后面并没有加任何表达式,这是可行的,这表示获取所有与CLS兼容或不兼容的异常。
            
//一旦发生错误,则将文件恢复到写入前的状态。
            catch
            {
                
if (fs != null)
                {
                    fs.Position 
= fsPosition; 
                    fs.SetLength(fsPosition);
                }
                
if (fs1 != null)
                {
                    fs1.Position 
= fs1Position;
                    fs1.SetLength(fs1Position);
                }
                
throw;
            }
            
//执行文件关闭操作。不管有没有引发异常。
            finally
            {
                
if (fs != null)
                {
                    fs.Close();
                }
                
if (fs1 != null)
                {
                    fs1.Close();
                }
            }
        }
    }
}

 

处理异常和错误>设计自己的异常

上面“从异常中恢复”,是简单地将系统异常抛出,现在设计抛出一个自定义的WriteFailedException类型的异常。

Program.cs
using System;
using System.Collections.Generic;
using System.Text;

namespace CustomException
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
try
            {
                WriteFile();
            }
            
catch (WriteFailedException ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
        
static void WriteFile()
        {
            
throw new WriteFailedException();
        }
    }
}

WriteFailedException.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace CustomException
{
    
/// <summary>
    
/// 自定义异常类的示例
    
/// </summary>
    public class WriteFailedException:ApplicationException
    {
        
public WriteFailedException()
            :
base("对两个文件的操作产生了一个异常")
        { 
        }
        
public WriteFailedException(string Message)
            : 
base(Message)
        { }
        
public WriteFailedException(string Message, Exception inner)
            : 
base(Message, inner)
        { }
    }
}

 

抱歉!评论已关闭.