Ipari zen

Szak-irodalom. A fejlesztő jajszava haikuban. A technika ördöge avagy a lelketlen vasban a mélyen emberi.

A szoftverfejlesztés művészete és a zen

2010.12.26. 22:53 Ipari zen

Hiányzó számla a zárszámadásnál

Címkék: c# aszinkron thread exception begininvoke endinvoke delegate

Mit előlegként
már megkaptál, ne várd a
végelszámolásnál.

Ahogy minden szoftverfejlesztőt, most éppen engem is utolért a végzet. Egy régebben C#-ban mások által megírt kódban kellett ad-hoc javítgatni egyet s mást, többek között egy el nem kapott exceptiont kellett valahogyan ártalmatlanná tenni. A probléma gyökere egy aszinkron függvényhívás mélyén rejtőzött, ahol az XML értelemző próbálta egy exceptionben a tudomásunkra hozni nemtetszését számunkra megfejthetetlen okból.

Mivel jobb ötletünk nem volt és a kód eredeti struktúrája  is ezt sugallta, szépen beleraktunk egy újabb catch blokkot az BeginInvoke-ot övező catch mögé, amint ez a lentebb mellékelt részleten is látszik piros színnel kiemelve és ez remekül megoldotta a problémát.

public void AsynchCallFunc()
{
MethodDelegate dlgt = new MethodDelegate (this.AsynchCalledMethod) ;
string s ;
int iExecThread;

AsyncCallback cb = new AsyncCallback(MyAsyncCallback);

try {
IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, cb, dlgt);
}
catch (IOException ioe){
MessageBox.Show ("file not found");
}
// utólag hozzáadva az ismeretlen eredetű exception elkapására
catch (Exception e){
MessageBox.Show ("unknown error"); }

}

Elszállás eltűnt és minden náttyon jó és minden náttyon szép volt, mindennel meg voltunk elégedve, ahogy Ferenc Jóska mondta volna. Csakhogy egy-két nap múlva kiderült, hogy egyúttal néhány igencsak szükséges konfigurációs hibajelzés is eltűnt a sülyesztőben.MInt később kiderült azért, mert az a kivételeket valamiért két szinten kezelte az eredeti szerző. Egy részüket a BeginInvoke-ot , egy másik részüket pedig az EndInvoke-ot övező try-catch-ben. A dokumentáció szerint és ezt az amatőr versenyző (mármint én) el is hitte, hogy az EndInvoke-nál a szál futása során felgyűlt összes kivételt megkapja a hívó. És ez igaz is, de csak akkor, ha a BeginInvoke-nál nincs hibakezelés és nem kap el az ember semmilyen exceptiont. Mert azokat a kivételeket, amiket az ember begyűjtött a BeginInvoke-nál már nem fogja megkapni az EndInvoke során. Mivel mi az EndInvoke-nál elkaptuk típusspecifikáció nélkül az összes exceptiont, hiába állt az EndInvoke után egy tucat catch a különféle exception-ök kezelésére, amint a mellékelt kódban, mert ezeknél már sohasem érkezett egyetlen kivétel sem. public void MyAsyncCallback(IAsyncResult ar)
{
string s ;
int iExecThread ;

MethodDelegate dlgt = (MethodDelegate) ar.AsyncState;

try {
   s = dlgt.EndInvoke (out iExecThread, ar) ;
} catch (IOException ioe){
   MessageBox.Show ("file not found");
} catch (XMLProcessingError xmle){
   MessageBox.Show ("XML error");
} catch (ConfigValueEXception cve){
   MessageBox.Show ("configuration error");
}

 Mivel a BeginInvoke is dobhat kivételt, ha valamilyen okból a végrehajtószálat nem tudja elindítani, a legegyszerűbb megközelítés az, ha valóban elkapunk minden exceptiont és a számunkra ismeretleneket továbbdobjuk. Ezeket a továbbdobott exception-öket majd módjában áll az EndInvoke hibakezelőjének tetszése szerint kezelni.  A BeginInvoke/EndInvoke párosról többet itt lehet olvasni.

Piszkos Thread, a kapitány

2 komment

A bejegyzés trackback címe:

https://ipari-zen.blog.hu/api/trackback/id/tr912540842

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Sopánka76 2011.01.14. 10:31:43

Úgy tanul a gyerök, ha kérdez.
Láthatnók a megoldást is?
Mi került a piros helyére?

Ipari zen · http://ipari-zen.blog.hu 2011.01.21. 21:47:36

@Sopánka76: A piros helyére nem került semmi, hanem a pirossal jelölt rész átkerült a MyAsyncCallback függvény hibakezelésének a legvégére.