Verileri bir uzak web hizmetinden aldığımız bir WPF 4.0 uygulaması geliştiriyorum. Web hizmeti, müşterilerine yaklaşık 120'den fazla yöntem sunar. WPF uygulamasından bir web hizmeti çağrısı başarısız olursa, bunu App.Config aracılığıyla yapılandırılabilir n kez tekrar denemeliyim. Bunu nasıl uygularsınız? Bu sorunu ele alan herhangi bir tasarım modeli var mı?C# için istisna durumunda n kere yeniden deneyin?
cevap
static T TryNTimes<T>(Func<T> func, int times)
{
while (times>0)
{
try
{
return func();
}
catch(Exception e)
{
if (--times <= 0)
throw;
}
}
}
ile katılıyorum Daha çok, ExecuteNTimes değil, TryNTimes olarak adlandırılmalıdır. –
Olmalı, onu düzenleyeceğim. Teşekkürler. –
Bu kodu çok uzun bir süre önce, istediğiniz şeye benzer bir şey yapmak için yazdım. İhtiyaçlarınıza uyacak şekilde değiştirilebilir. Genel bekleme yöntemi. Bir işlevden geçirin ve beklenen sonuç iade edilmezse, bekleyin ve ardından X sayısı denemeden sonra tekrar deneyin.
/// <summary>
/// Wait for the result of func to return the expeceted result
/// </summary>
/// <param name="func">Function to execute each cycle</param>
/// <param name="result">Desired result returned by func</param>
/// <param name="waitInterval">How long to wait (ms) per cycle </param>
/// <param name="cycles">How many times to execute func before failing</param>
/// <returns>True if desired result was attained. False if specified time runs out before desired result is returned by func</returns>
protected static bool WaitForEvent(Func<bool> func, bool result, int waitInterval, int cycles)
{
int waitCount = 0;
while (func() != result)
{
if (waitCount++ < cycles)
{
Thread.Sleep(waitInterval);
}
else
{
return false;
}
}
return true;
}
Aynı şeyi yazmak üzereydi. Aferin :-) –
Her girişim ile bekleme aralığını artırmak için iyi bir fikir olabilir. – CodesInChaos
ya da (waitCount ++
while(retries < maxTries)
try
{
//retryable code here
break;
}
catch(Exception ex)
{
if(++retries == maxTries)
throw;
continue;
}
Kesinlikle hiçbir şey fantezi ama işi edeceğiz. Hemen hemen her uygulamada ortak olacak olan ana desen, bir deneyin yakalanmasını içeren ve bir şekilde kontrol edilen bir döngü yapısıdır; Bu, yinelemeli bir çağrı veya yukarıdaki while döngüsü gibi yinelemeli bir döngü olabilir. Başarılı bir denemeden sonra döngüden düzgün bir şekilde çıktığınızdan emin olun ve tekrar deneme sayısını takip edin; Ya başarısızlık sonsuz bir döngüye sebep olur.
Ve eğer bunu bir işleve koyarsa, 120 + yöntem çağrıları için merkezi bir noktası vardır. –
Tanımlanmış herhangi bir bekleme aralığına sahip görünmüyor – NotMe
Bekleme her zaman gerekli değildir; try bloğunda tam olarak ne yapmaya çalıştığınıza bağlıdır. Başarısız bir denemeden sonra uzak bir bilgisayarın temizlendiğinden emin olmanız gerekiyorsa, her şey beklemek demektir. Ancak, Thread.Sleep() dikkatli kullanılmalıdır veya uygulamanın yanıt vermemesine neden olur; Bu, temiz bir şekilde böyle bir şey uygulamak için yapmanız gerekenleri genişletir. – KeithS
while(true)
{
try
{
Method();
break;
}
catch(Exception ex)
{
i++;
if(i == n) throw ex;
}
}
İşte IO paylaşım ihlali sarar benzer bir koddur. Aynı fikir: Daha sonra
/// <summary>
/// Defines a sharing violation wrapper delegate.
/// </summary>
public delegate void WrapSharingViolationsCallback();
/// <summary>
/// Wraps sharing violations that could occur on a file IO operation.
/// </summary>
/// <param name="action">The action to execute. May not be null.</param>
/// <param name="exceptionsCallback">The exceptions callback. May be null.</param>
/// <param name="retryCount">The retry count.</param>
/// <param name="waitTime">The wait time in milliseconds.</param>
public static void WrapSharingViolations(WrapSharingViolationsCallback action, WrapSharingViolationsExceptionsCallback exceptionsCallback, int retryCount, int waitTime)
{
if (action == null)
throw new ArgumentNullException("action");
for (int i = 0; i < retryCount; i++)
{
try
{
action();
return;
}
catch (IOException ioe)
{
if ((IsSharingViolation(ioe)) && (i < (retryCount - 1)))
{
bool wait = true;
if (exceptionsCallback != null)
{
wait = exceptionsCallback(ioe, i, retryCount, waitTime);
}
if (wait)
{
Thread.Sleep(waitTime);
}
}
else
{
throw;
}
}
}
}
Ve biz (mükemmel burada lambda ifade giysileri) bu şekilde diyoruz:
WrapSharingViolations(() => DoWhatever(...));
Bir fonksiyonel kullanabilirsiniz bir temsilci ve bir sarıcı statik yöntemine sahip yaklaşım:
class Program
{
static T Retry<T, TException>(Func<T> thingToTry, int timesToRetry)
where TException : Exception
{
// Start at 1 instead of 0 to allow for final attempt
for (int i = 1; i < timesToRetry; i++)
{
try
{
return thingToTry();
}
catch (TException)
{
// Maybe: Trace.WriteLine("Failed attempt...");
}
}
return thingToTry(); // Final attempt, let exception bubble up
}
static int ServiceCall()
{
if (DateTime.Now.Ticks % 2 == 0)
{
throw new InvalidOperationException("Randomly not working");
}
return DateTime.Now.Second;
}
static void Main()
{
int s = Retry<int, InvalidOperationException>(ServiceCall, 10);
}
}
Özel istisnalar yakalamak için bunu kullanabilirsiniz (gerekirse daha fazla TEXception genel parametresi ekleyin).
Neden özyinelemeli kullanıyorsunuz? Performans ve bellek sorunları, bir yığın taşma olasılığından bahsetmeyeceğiniz (ortaya koyduğunuz gibi) ortaya çıkacaktır. İyi deneme, ama kötü tasarım IMO. –
İyi nokta. Son zamanlarda çok fazla fonksiyonel kodlama yapıyorum. Sabit. –
Aslında herhangi bir performans ve bellek sorunu yaşamadan önce çok fazla denemelisiniz. –
Sen ile bunu mümkün olabilir bir GOTO
(gasp)
int count = 0;
try
{
TryAgain:
// Do something with your web service
}
catch(Exception e)
{
if(count < numberOfAttemptsAllowed)
{
count++;
goto TryAgain;
}
}
daha iyi bir yolu olabilir eminim ama bu gerekenleri yapabilir.
- 1. Hata durumunda jquery ajax'ı yeniden deneyin
- 2. "N kere tekrarla" deyimi?
- 3. Yinelenen vektör elemanlarını N kere tekrar edin
- 4. JavaScript iç içe deneyin istisna
- 5. MySQL/SQLAlchemy için kilitlenmeyi yeniden deneyin
- 6. [-n "$ {TEMP_FILE_LIST}"] öğesinin ne yapması durumunda -n nedir?
- 7. yayılan C++ istisna Cython için - piton istisna
- 8. Java'da zaman aşımında bir bağlantıyı yeniden deneyin.
- 9. JNI_CreateJavaVM: Hata durumunda bir istisna atarsam arabellek taşması
- 10. Yinelenen ifadede R uyarı iletisi: Başarısız olursa, yeniden deneyin. Yeniden deneyin.
- 11. RxJS catch ** ve ** Gözlemlenebilir bir yeniden deneyin
- 12. Varchar değerini hatalı giriş durumunda bir istisna atmadan dönüştürmek
- 13. Bir n n^^^^^^^^^^^^ (örneğin “aaabbbccc”) C#
- 14. İstisna API yeniden adlandırma kuralı
- 15. C# Grafikler n Grafikler
- 16. n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n bana 1 * 1 olmalıdır. bunun yerine 2 * 2
- 17. N-ary ağaçları C
- 18. OSX'de Karbon C uygulaması için istisna sarıcısı
- 19. Logging.error() kaç kere çağrıldı?
- 20. "Yeniden yürütme" ve "autoConnect" kullanıldığında istisna daha fazla istisna "
- 21. WSO2 ESB: zaman aşımından sonra HTTP isteğini yeniden deneyin
- 22. deneyin, deneyin! & Deneyin? fark nedir ve ne zaman kullanılır?
- 23. deneyin .... işlem için mysql yakalayın?
- 24. C dizisini n eşit parçalara ayırma
- 25. Java vs Nullpointer istisnası durumunda Objective C
- 26. javascript bölünmüş ('\ n') ve değil ('\ n \ n')
- 27. Linux'ta C++ olmadan İstisna İşlemi C++
- 28. MYSQL ifadesi n: n tablosundan grup seçmek için kullanılır
- 29. Standart istisna sınıfları C++ kitaplığında
- 30. Scala: sürgülü (N, N) ve gruplandırılmış (N)
Bu desenin kendi kendini iyi oluşturmadığını unutmayın. Dört kez yeniden deneyen bir işlev, dört kez yeniden deneyen ve dört kez yeniden deneyen bir işlevi çağıran bir işlev çağırırsa, son işlem 64 kez yeniden denenir. Yeniden denemeler arasında 30 saniye beklerse, kullanıcı hata mesajını beklemek için yarım saat bekler. Bu desene şiddetle tavsiye ederim. Bir şey başarısız olduğunda, * hemen * durdurun, kullanıcıyı anlatın ve yeniden denemeye karar verip vermeyeceğine veya yönlendiricinin fişten çekip çekmediğine karar vermesine izin verin. WPF Apps için –
Ofcourse, yeniden deneme numarası yüksek olmayacak! Yine de, bu arka plan işlemleri gerçekleştiren konsol uygulamaları için oldukça kullanışlıdır. – funwithcoding
Ne yaptın? Bir cevabı işaretlemeyi unutma? –