[C#] Verschillende stukken code wrappen in zelfde try/catch

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Beetje vreemde topic titel, maar zal het verduidelijken. Ik ben nieuw met C#, dus kan er compleet naast zitten.

Ik ben bezig met een applicatie die nogal wat bestands acties doet zoals kopiëren, hernoemen, enz. Soms zijn bestanden nog in gebruik en moet ik een bepaalde actie nogmaals proberen.

Hiervoor had ik deze methode geschreven:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        delegate void RetryDelegate();

        private void AutoRetry(int timeOutSecs, RetryDelegate p)
        {
            bool success = false;
            bool timeOut = false;
            DateTime start = DateTime.Now;
            while ((!success) && (!timeOut))
            {
                try
                {
                    p();
                    success = true;
                }
                catch (IOException)
                {
                    success = false;
                    Thread.Sleep(1000);
                }
                timeOut = (DateTime.Now.Subtract(start).TotalSeconds > timeOutSecs);
            }
        }


Dit werkt goed, maar niet als ik het volgende ga doen:
code:
1
2
3
4
5
            FileInfo newFile;
            AutoRetry(60, delegate()
            {
                newFile = CreateNewFile("test");
            });

Ik kan da newFile niet gebruiken omdat deze unassigned zou zijn.

Hoe gebruik ik in C# steeds hetzelfde try/catch + extra's blok zonder deze te hoeven copy & pasten?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
Je krijgt die melding, omdat de compiler niet zeker weet dat newFile assigned is.
Je kan die warning omzeilen door
code:
1
FileInfo newFile = null;

te doen, denk ik.
Daarna wel checken of newFile null is.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Oke, dat ga ik gebruiken. Bedankt.

Maar is de methode die ik gebruik een juiste oplossing voor dit probleem?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Acties:
  • 0 Henk 'm!

  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 10:39
Hierbij zeg ik niet of het een juiste oplossing is, maar je zou de Stopwatch kunnen gebruiken voor de timeout controle.

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Nu online
jelmervos schreef op dinsdag 29 september 2009 @ 09:38:
Oke, dat ga ik gebruiken. Bedankt.

Maar is de methode die ik gebruik een juiste oplossing voor dit probleem?
Ik vind het maar een vieze oplossing eigenlijk ....
Hoe komt het dat die bestanden nog in gebruik kunnen zijn ?
Wat doe je met die bestanden ?
Kan je niet wachten tot wanneer die bestanden niet meer gelocked zijn ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
whoami schreef op dinsdag 29 september 2009 @ 09:48:
[...]

Hoe komt het dat die bestanden nog in gebruik kunnen zijn ?
Andere processen kunnen er nog naar schrijven, vooral bij grotere bestanden kan dit voorkomen.
Wat doe je met die bestanden ?
Ik maak een service welke inkomende bestanden via bijvoorbeeld FTP verwerkt (verplaatsen, decrypteren/encrypteren, hernoemen). Dit moet zo robuust mogelijk zijn.
Kan je niet wachten tot wanneer die bestanden niet meer gelocked zijn ?
Dat probeerde ik dus te maken.

[ Voor 4% gewijzigd door jelmervos op 29-09-2009 09:52 ]

"The shell stopped unexpectedly and Explorer.exe was restarted."


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
Waarom catch je daar IOException. De AutorRetry methode zou in princiepe voor vanalles gebruikt kunnen worden. Dus of verander die IOException naar Exception(?) of pas de delegate aan dat hij een boolean teruggeeft of de operatie gelukt is en gebruik dat.(netter).
Andersom kun je ook de naam van de delegate aanpassen en daarin aangeven dat het om IO operaties gaat.

Daarnaast realiseer je wel dat IOException valles kan zijn. Er kunnen dingen optreden die niks met locking te maken hebben. Hoe ga je dat afvangen? Op dit moment wordt de exception opgevreten waardoor je geen idee hebt waarom het mis is gegaan.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Die delegate heeft wat veel side-effects die de compiler niet kan zien aankomen. Waarom laat je die niet gewoon een waarde retourneren? Even uit de losse pols:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    public static TResult WithAutoRetryIO<TResult>(int seconds, Func<TResult> p)
    {
        Stopwatch watch = new Stopwatch();
        IOException lastException;
        watch.Start();
        do
        {
            try
            {
                return p();
            }
            catch (IOException e)
            {
                lastException = e;
            }
            Thread.Sleep(1000);
        } while (watch.ElapsedMilliseconds < seconds * 1000);
        throw lastException;
    }
    ....
            FileInfo newFile = WithAutoRetryIO(60, delegate()
            {
               return CreateNewFile("test");
            });

Enkel van Thread.Sleep wordt je natuurlijk nooit echt vrolijk... ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ah, dat ziet er goed uit. Bedankt.
Ik heb tevens nog eens goed gekeken naar mijn ontwerp, en heb het nu minder hard nodig. Het is beter gewoon zoveel mogelijk excepties afvangen zoals je die verwacht en dan handelen.

Het geheel draait in een aparte thread, dus Thread.Sleep moet toch geen probleem zijn?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
jelmervos schreef op dinsdag 29 september 2009 @ 19:20:
Het geheel draait in een aparte thread, dus Thread.Sleep moet toch geen probleem zijn?
Dat bedoel ik niet. Het is natuurlijk veel mooier als je niet steeds een tijdje wacht en opnieuw probeert, maar wacht totdat het probleem waarop je wacht is opgelost. :) Eens soort WaitHandle-constructie bijvoorbeeld.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Dat klopt, maar hoe weet ik wanneer een file niet meer in gebruik ik door een ander process?

"The shell stopped unexpectedly and Explorer.exe was restarted."


Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 17-09 23:59

TeeDee

CQB 241

Heb je controle over dat andere process? Zo ja, dan zou je dat process een Event (Finished, Changed oid) op kunnen laten gooien en afvangen. Mogelijk heb je voor het gemak ook meer aan het FileSystemWatcher gedeelte. Gooit ook nette events op ;)

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Topicstarter
Ik heb geen controle over het andere process, dit kan een FTP server zijn, een Windows share of een andere applicatie.
FileSystemWatcher gebruik ik al, en dan alleen het event OnCreated. Dit werkt goed, alleen bij grote bestanden duurt het even voordat het bestand toegankelijk is. Misschien kan ik hier wat aan doen, maar liever heb ik een robuuste service die tegen een stootje kan.

"The shell stopped unexpectedly and Explorer.exe was restarted."

Pagina: 1