try-catch (C# Başvurusu)
try-catch deyimi, farklı özel durumlar için işleyicileri belirten bir veya daha fazla yan tümcenin takip try catch ettiği bir bloktan oluşur.
Bir özel durum thrown, ortak dil çalışma zamanı (CLR) bu catch özel durumu işlemek deyimini için. Şu anda yürütülen yöntem böyle bir blok içeriyorsa CLR, geçerli yöntemi çağıran yönteme ve çağrı yığınına bakarak devam catch ediyor. Herhangi catch bir blok bulunamasa CLR kullanıcıya işlanmamış bir özel durum iletisi görüntüler ve programın yürütülmesini durdurur.
Blok, try özel durumlara neden olan korumalı kodu içerir. Bir özel durum ana kadar veya başarıyla tamamlanana kadar blok yürütülür. Örneğin, aşağıdaki bir nesne oluşturma null girişimi özel durumu NullReferenceException oluşturur:
object o2 = null;
try
{
int i2 = (int)o2; // Error
}
yan tümcesi herhangi bir özel durumu yakalamak için bağımsız değişkenler olmadan catch kullanılabilir, ancak bu kullanım önerilmez. Genel olarak, yalnızca kurtarmayı biliyor olduğunuz özel durumları yakalamalısiniz. Bu nedenle, her zaman'dan türetilen bir nesne bağımsız değişkeni belirtmeniz System.Exception gerekir. Özel durum işleyicinizin gerçekten çözemezse özel durumların yanlış kabul edilmesini önlemek için, özel durum türü mümkün olduğunca özel durum türüne özgü olması gerekir. Bu nedenle, temel tür yerine somut özel durumları tercih Exception edersiniz. Örneğin:
catch (InvalidCastException e)
{
// recover from exception
}
Aynı try-catch deyiminde birden catch fazla belirli yan tümcesi kullanmak mümkündür. Bu durumda yan tümceler catch sırayla incelendiğinden catch yan tümcelerinin sırası önemlidir. Daha az belirli özel durumlardan önce daha belirli özel durumları yakalar. Sonraki bir bloka hiçbir zaman ulaşılamayacak şekilde catch bloklarınızı sipariş ettiyebilirsiniz, derleyici bir hata üretir.
Bağımsız catch değişkenleri kullanmak, işlemek istediğiniz özel durumları filtrelemenin bir yoludur. Ayrıca, özel durumu daha ayrıntılı inceleyen bir özel durum filtresi kullanarak işlenecek olup olmadığını saptayıp karara varmayylarını da kullanabilirsiniz. Özel durum filtresi false döndürürse, işleyici arama devam eder.
catch (ArgumentException e) when (e.ParamName == "…")
{
// recover from exception
}
Özel durum filtreleri yakalama ve yeniden azaltma tercih edilir (aşağıda açıklanmıştır) çünkü filtreler yığının güvenliksiz bırakır. Daha sonraki bir işleyici yığının dökümlerini alıyorsa, özel durumun yalnızca yeniden atılmış olduğu son yer yerine ilk geldiği yeri görebilir. Özel durum filtre ifadelerinin yaygın bir kullanımı günlüğe kaydetmedir. Her zaman false döndüren ve aynı zamanda bir günlüğe çıkışını da döndüren bir filtre oluşturabilirsiniz. Özel durumları işlerine gerek kalmadan ve yeniden oluşturmak zorunda kalmadan günlüğe sızan özel durumları günlüğe sızdır.
Throw deyimi, deyimi tarafından yakalanan catch özel durumu yeniden atmak için bir blokta catch kullanılabilir. Aşağıdaki örnek, bir özel durumdan kaynak IOException bilgilerini ayıklar ve ardından özel durumu üst yönteme oluşturur.
catch (FileNotFoundException e)
{
// FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
// Extract some information from this exception, and then
// throw it to the parent method.
if (e.Source != null)
Console.WriteLine("IOException source: {0}", e.Source);
throw;
}
Bir özel durumu yakalayabilir ve farklı bir özel durum oluşturur. Bunu gerçekleştirerek, aşağıdaki örnekte gösterildiği gibi, iç özel durum olarak yakaladığımız özel durumu belirtin.
catch (InvalidCastException e)
{
// Perform some action here, and then throw a new exception.
throw new YourCustomException("Put your error message here.", e);
}
Ayrıca, aşağıdaki örnekte gösterildiği gibi belirtilen bir koşul true olduğunda da bir özel durumu yeniden attırın.
catch (InvalidCastException e)
{
if (e.Data == null)
{
throw;
}
else
{
// Take some action.
}
}
Not
Benzer sonucu genellikle daha temiz bir şekilde (bu belgenin önceki sürümlerinde de belirtildiği gibi, yığını değiştirmeden) almak için özel durum filtresi de kullanabilirsiniz. Aşağıdaki örnek, önceki örnek gibi arayanlar için benzer bir davranışa sahip. işlevi olduğunda InvalidCastException çağrıyı yapana geri e.Data null atar.
catch (InvalidCastException e) when (e.Data != null)
{
// Take some action.
}
Bir try bloğun içinden yalnızca burada bildirilen değişkenleri başlat. Aksi takdirde, bloğun yürütülmesi tamamlanmadan önce bir özel durum oluşabilir. Örneğin, aşağıdaki kod örneğinde değişkeni n bloğun içinde try başlatılır. Deyiminde bu değişkeni bloğun try dışında kullanma girişimi bir derleyici Write(n) hatasına neden olur.
static void Main()
{
int n;
try
{
// Do not initialize this variable here.
n = 123;
}
catch
{
}
// Error: Use of unassigned local variable 'n'.
Console.Write(n);
}
catch hakkında daha fazla bilgi için bkz. try-catch-finally.
Zaman uyumsuz yöntemlerde özel durumlar
Zaman uyumsuz bir yöntem zaman uyumsuz değiştiriciyle işaretlenir ve genellikle bir veya daha fazla await ifadesi veya deyimi içerir. Await ifadesi, await işlecini veya 'ye Task Task<TResult> uygular.
Zaman uyumsuz await yöntemde denetim bir'e ulaştığında, beklenen görev tamamlandıktan sonra yöntemde ilerleme askıya alınır. Görev tamamlandığında, yürütme yönteminde sürdürebilirsiniz. Daha fazla bilgi için bkz. Async ve await ile zaman uyumsuz programlama.
Uygulanan tamamlanan görev, görevi döndüren yöntemde işlanmamış bir özel durum await nedeniyle hatalı durumda olabilir. Görevi beklerken bir özel durum oluşturur. Bir görev, onu döndüren zaman uyumsuz işlem iptal edilirse iptal edilmiş durumda da olabilir. İptal edilen bir görevi beklerken bir OperationCanceledException atar.
Özel durumu yakalamak için, görevi bir try blokta bekler ve ilişkili blokta özel durumu catch yakalar. Bir örnek için Async yöntemi örnek bölümüne bakın.
Beklenen zaman uyumsuz yöntemde birden çok özel durum meydana geldiği için bir görev hatalı durumda olabilir. Örneğin, görev çağrısının sonucu Task.WhenAll olabilir. Böyle bir görevi beklerken, özel durumlardan yalnızca biri yakalır ve hangi özel durumun yakalanacaklarını tahmin etmek mümkün değildir. Örnek için Task.WhenAll örnek bölümüne bakın.
Örnek
Aşağıdaki örnekte, bloğu try bir özel durum neden olabilir ProcessString yöntemine bir çağrı içerir. yan catch tümcesi yalnızca ekranda bir ileti görüntüleyen özel durum işleyicisini içerir. içinden throw deyimi çağrıldı ProcessString zaman, sistem deyimini arayıp catch iletiyi Exception caught görüntüler.
class TryFinallyTest
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException(paramName: nameof(s), message: "parameter can't be null.");
}
}
public static void Main()
{
string s = null; // For demonstration purposes.
try
{
ProcessString(s);
}
catch (Exception e)
{
Console.WriteLine("{0} Exception caught.", e);
}
}
}
/*
Output:
System.ArgumentNullException: Value cannot be null.
at TryFinallyTest.Main() Exception caught.
* */
İki catch bloğu örneği
Aşağıdaki örnekte iki catch bloğu kullanılmıştır ve ilk olarak gelen en özel durum yakalandı.
En az belirli özel durumu yakalamak için, içinde throw deyimini aşağıdaki ProcessString deyimle değiştirebilirsiniz: throw new Exception() .
Örnekte en az belirli catch bloğuna ilk olarak yer alırsanız şu hata iletisi görüntülenir: A previous catch clause already catches all exceptions of this or a super type ('System.Exception') .
class ThrowTest3
{
static void ProcessString(string s)
{
if (s == null)
{
throw new ArgumentNullException(paramName: nameof(s), message: "Parameter can't be null");
}
}
public static void Main()
{
try
{
string s = null;
ProcessString(s);
}
// Most specific:
catch (ArgumentNullException e)
{
Console.WriteLine("{0} First exception caught.", e);
}
// Least specific:
catch (Exception e)
{
Console.WriteLine("{0} Second exception caught.", e);
}
}
}
/*
Output:
System.ArgumentNullException: Value cannot be null.
at Test.ThrowTest3.ProcessString(String s) ... First exception caught.
*/
Zaman uyumsuz yöntem örneği
Aşağıdaki örnek, zaman uyumsuz yöntemler için özel durum işlemeyi göstermektedir. Zaman uyumsuz bir görevin neden olduğu bir özel durumu yakalamak için, ifadeyi bir bloğuna yer ve await özel durumu bir try blokta catch yakalar.
Özel durum throw new Exception işlemeyi göstermek için örnekteki satırın yorumlarını geri anın. Görevin özelliği olarak ayarlanır, görevin özelliği özel durum olarak ayarlanır ve IsFaulted True özel durum Exception.InnerException bloğunda catch yakalır.
Zaman uyumsuz bir throw new OperationCanceledException işlemi iptal edin ve ne olacağını göstermek için satırın açıklarını seçin. Görevin özelliği IsCanceled olarak ayarlanır true ve özel durum bloğunda catch yakalır. Bu örnekte geçerli olan bazı koşullar altında, görevin özelliği olarak ayarlanır ve IsFaulted true olarak IsCanceled false ayarlanır.
public async Task DoSomethingAsync()
{
Task<string> theTask = DelayAsync();
try
{
string result = await theTask;
Debug.WriteLine("Result: " + result);
}
catch (Exception ex)
{
Debug.WriteLine("Exception Message: " + ex.Message);
}
Debug.WriteLine("Task IsCanceled: " + theTask.IsCanceled);
Debug.WriteLine("Task IsFaulted: " + theTask.IsFaulted);
if (theTask.Exception != null)
{
Debug.WriteLine("Task Exception Message: "
+ theTask.Exception.Message);
Debug.WriteLine("Task Inner Exception Message: "
+ theTask.Exception.InnerException.Message);
}
}
private async Task<string> DelayAsync()
{
await Task.Delay(100);
// Uncomment each of the following lines to
// demonstrate exception handling.
//throw new OperationCanceledException("canceled");
//throw new Exception("Something happened.");
return "Done";
}
// Output when no exception is thrown in the awaited method:
// Result: Done
// Task IsCanceled: False
// Task IsFaulted: False
// Output when an Exception is thrown in the awaited method:
// Exception Message: Something happened.
// Task IsCanceled: False
// Task IsFaulted: True
// Task Exception Message: One or more errors occurred.
// Task Inner Exception Message: Something happened.
// Output when a OperationCanceledException or TaskCanceledException
// is thrown in the awaited method:
// Exception Message: canceled
// Task IsCanceled: True
// Task IsFaulted: False
Task.WhenAll örneği
Aşağıdaki örnek, birden çok görevi birden çok özel durumla sonuçlandırarak özel durum işlemeyi gösterir. tryBlok, çağrısı tarafından döndürülen görevi Task.WhenAll bekler. WhenAll'ın uygulandığı üç görev tamamlandığında görev tamamlanır.
Üç görevden her biri bir özel durum oluşturur. catchBlok, tarafından döndürülen görevin özelliğinde bulunan özel durumlar Exception.InnerExceptions aracılığıyla Task.WhenAll tekrarlar.
public async Task DoMultipleAsync()
{
Task theTask1 = ExcAsync(info: "First Task");
Task theTask2 = ExcAsync(info: "Second Task");
Task theTask3 = ExcAsync(info: "Third Task");
Task allTasks = Task.WhenAll(theTask1, theTask2, theTask3);
try
{
await allTasks;
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.Message);
Debug.WriteLine("Task IsFaulted: " + allTasks.IsFaulted);
foreach (var inEx in allTasks.Exception.InnerExceptions)
{
Debug.WriteLine("Task Inner Exception: " + inEx.Message);
}
}
}
private async Task ExcAsync(string info)
{
await Task.Delay(100);
throw new Exception("Error-" + info);
}
// Output:
// Exception: Error-First Task
// Task IsFaulted: True
// Task Inner Exception: Error-First Task
// Task Inner Exception: Error-Second Task
// Task Inner Exception: Error-Third Task
C# dili belirtimi
Daha fazla bilgi için C# dil belirtimlerinin try deyimi bölümüne bakın.