Câu lệnh finally trong csharp

c-sharp

(Phạm Quyết Nghị) #1

Trong một số tình huống, việc phát sinh ngoại lệ và unwind stack có thể tạo ra một số vấn đề. Ví dụ như nếu chúng ta mở một tập tin hay trường hợp khác là xác nhận một tài nguyên, chúng ta có thể cần thiết một cơ hội để đóng một tập tin hay là giải phóng bộ nhớ đệm mà chương trình đã chiếm giữ trước đó.

Ghi chú: Trong ngôn ngữ C#, vấn đề này ít xảy ra hơn do cơ chế thu dọn tự động của C# ngăn ngừa những ngoại lệ phát sinh từ việc thiếu bộ nhớ.

Tuy nhiên, có một số hành động mà chúng ta cần phải quan tâm bất cứ khi nào một ngoại lệ được phát sinh ra, như việc đóng một tập tin, chúng ta có hai chiến lược để lựa chọn thực hiện. Một hướng tiếp cận là đưa hành động nguy hiểm vào trong khối try và sau đó thực hiện việc đóng tập tin trong cả hai khối catchtry. Tuy nhiên, điều này gây ra đoạn chương trình không được đẹp do sử dụng trùng lắp lệnh. Ngôn ngữ C# cung cấp một sự thay thế tốt hơn trong khối finally.

Đoạn chương trình bên trong khối catch được đảm bảo thực thi mà không quan tâm đến việc khi nào thì một ngoại lệ được phát sinh. Phương thức TestFunc() trong ví dụ 13.5 minh họa việc mở một tập tin như là hành động đầu tiên của nó, sau đó phương thức thực hiện một vài các phép toán toán học, và sau đó là tập tin được đóng. Có thể trong quá trình mở tập tin cho đến khi đóng tập tin chương trình phát sinh ra một ngoại lệ. Nếu xuất hiện ngoại lệ, và khi đó tập tin vẫn còn mở. Người phát triển biết rằng không có chuyện gì xảy ra, và cuối của phương thức này thì tập tin sẽ được đóng. Do chức năng đóng tập tin được di chuyển vào trong khối finally, ở đây nó sẽ được thực thi mà không cần quan tâm đến việc có phát sinh hay không một ngoại lệ trong chương trình.

Ví dụ 13.5: Sử dụng khối finally.

namespace Programming_CSharp
{
	using System;
	public class Test
	{
		public static void Main()
		{
			Test t = new Test();
			t.TestFunc();
		}
		
		// chia hai số và xử lý ngoại lệ nếu có
		public void TestFunc()
		{
			try
			{
				Console.WriteLine(“Open file here”);
				double a = 5;
				double b = 0;
				Console.WriteLine(“{0} /{1} = {2}”, a, b, DoDivide(a,b));
				Console.WriteLine(“This line may or not print”);
			}
			catch (System.DivideByZeroException)
			{
				Console.WriteLine(“DivideByZeroException caught!”);
			}
			catch
			{
				Console.WriteLine(“Unknown exception caught”);
			}
			finally
			{
				Console.WriteLine(“Close file here.”);
			}
		}			

		// thực hiện chia nếu hợp lệ
		public double DoDivide(double a, double b)
		{
			if ( b == 0)
			{
				throw new System.DivideByZeroException();
			}
			
			if ( a == 0)
			{
				throw new System.ArithmeticException();
			}
			
			return a/b;
		}
	}
}

Kết quả:

Open file here
DivideByZeroException caught!
Close file here.
Kết quả trong trường hợp b = 12
Open file here
5/ 12 = 0.416666666666
Close file here

Trong ví dụ này một khối catch được loại bỏ và thêm vào khối finally. Bất cứ khi một ngoại lệ có được phát sinh ra hay không thì khối lệnh bên trong finally cũng được thực thi. Do vậy nên trong cả hai trường hợp ta cũng thấy xuất hiện thông điệp “Close file here”.


89% Thành viên có cách giải cho một câu hỏi. Bạn thì sao?