Pertanyaan Mencegah StackOverFlow dalam fungsi rekursif


Saya memiliki fungsi rekursif dalam BaseClass yang bergantung pada a protected virtual berfungsi untuk mengembalikan kondisi itu.

Kelas anak dapat mengesampingkan fungsi ini secara tidak benar dan mengarah ke a StackOverFlow pengecualian. Hal terburuk adalah ada beberapa panggilan jaringan yang lambat dan pengecualian tidak akan segera terjadi (banyak sumber daya yang terbuang untuk waktu yang lama).

Saya mencari metode untuk memeriksanya StackOverFlow pada tahap awal beberapa cara di kelas dasar (mungkin menggunakan Reflection dan tingkat rekursi saat ini).

Ada ide ?


8
2018-01-28 06:31


asal


Jawaban:


Anda bisa melewatkan 'kedalaman' integer sederhana ke fungsi rekursif dan menaikkannya dengan setiap panggilan berikutnya. Jika mendapat lebih besar dari kedalaman maksimum yang diizinkan, lempar Eksepsi ke kanan daripada menunggu hingga terlambat dan ditakuti StackOverflow pengecualian telah terjadi.

Mekanisme keamanan seperti itu (penghitung kenaikan, periksa itu tidak terlalu besar) juga bisa berguna while loop di mana kesalahan kecil dapat menyebabkan loop tak terbatas memakan banyak CPU.

Dalam sistem besar dengan banyak pengguna (misalnya situs web) terkadang sebaiknya mengambil tindakan pencegahan seperti ini dengan rekursi dan sementara loop karena konsekuensinya dapat menjangkau jauh melampaui satu laman web atau satu pengguna sistem. Ini bukan kode cantik dan orang-orang puritan tidak akan ragu menolaknya, tapi itu efisien, defensif dan pragmatis.


9
2018-01-28 06:43



Selesaikan masalah alih-alih membuat solusi. Buat fungsi pribadi yang bersifat rekursif yang memanggil fungsi virtual yang dilindungi.


1
2018-01-28 06:36



Meskipun Anda mungkin dapat membaca tumpukan panggilan dan menganalisisnya, saya tidak akan melakukannya.

  1. Ini akan memperlambat eksekusi
  2. Ini bukan tanggung jawab kelas dasar Anda
  3. Dokumentasikan perilaku kelas dasar Anda

Alternatif lain adalah dengan melakukan analisis tumpukan panggilan dalam mode DEBUG saja. Berikut ini adalah kode kecil untuk melihat cara mendapatkan tumpukan panggilan.

using System.Diagnostics;

[STAThread]
public static void Main()
{
  StackTrace stackTrace = new StackTrace();           // get call stack
  StackFrame[] stackFrames = stackTrace.GetFrames();  // get method calls (frames)

  // write call stack method names
  foreach (StackFrame stackFrame in stackFrames)
  {
    Console.WriteLine(stackFrame.GetMethod().Name);   // write method name
  }
}

Dari situs ini


0
2018-01-28 06:38