Exception DLL afvangen in de aanroepende klasse (Visual C#)

Pagina: 1
Acties:

Onderwerpen

Vraag


  • Tokkes
  • Registratie: September 2011
  • Laatst online: 12-12-2022
Allen

Ik ben aan een projectje bezig om een beetje terug in het programmeren te komen. Op hoog niveau heb ik, zoals wel zal te merken zijn, nog geen ervaring.

Nu loop ik ergens tegenaan waar ik geen blijf mee weet.
Heb al half StackOverflow afgezocht, tutorials gezocht, MSDN afgegaan kom ik er nog steeds niet uit.

Ik heb mijn klasse in mijn applicatie, deze zit achter mijn WinForm.
In deze klasse neem ik de waarden uit textboxes in mijn WinForm en gebruik deze om te verbinden naar een server. De logica om te verbinden zal door nog een 2de project in dezelfde solution gebruikt worden, daarom zet ik ze in een Class Library en het leek me handig ook meteen te leren werken met Class Libraries.

Deze Class library lijkt zijn werk goed te doen - tenzij er een exception optreed bij het verbinden (timeout of....).

Ik krijg deze exception NIET opgevangen in de WinForm klasse om de foutmelding dan aan de gebruiker te serveren.

C#: ClientConnect.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ClientConnect
{
    public void ConnectToServer(IPEndPoint ip, string type, string name)
    {      
        clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        ipEndPoint = ip;
        strName = name;
        strTypeOfCLient = type;

        clientSock.BeginConnect(ip, new AsyncCallback(LoginToServer), clientSock);
    }

    public void LoginToServer(IAsyncResult AR)
    {
        
            clientSock.EndConnect(AR); // This statement is where it goes wrong.
        // .. hier hoort meer te komen
    }
}


C#: CarbonCatsMain.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class CarbonCats_Main
{
    private static ClientConnection clientcon;

    private void btnConnect_Click(object sender, EventArgs e)
    {
        //placeholder for making the connection to "Mother Base"
        int port = Int32.Parse(txtPort.Text);
        System.Net.IPAddress ipA = System.Net.IPAddress.Parse(txtServer.Text);
        System.Net.IPEndPoint ipE = new System.Net.IPEndPoint(ipA,port);

        try
        {
            clientcon.ConnectToServer(ipE, "Cat", txtName.Text);                
        }
        catch (Exception ex)
        {
            MessageBox.Show("An error occurred! are you sure the server is online? \n" +
            "Here is more information: \n" + ex.Message, "Carbon Cats", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
        }
    }
}


Volgens wat ik vond zouden exceptions gewoon moeten doorstromen naar de caller... maar mijn app blijft crashen.

Voor de volledige code kan je terecht op GitHub.
https://github.com/ProfessorZ/DiamondDogs/

Op dit moment forceer ik een MessageBox vanuit de DLL maar dit lijkt me niet de bedoeling - de DLL wordt er zo enorm platformafhankelijk van en dat probeer ik te vermijden.

[ Voor 4% gewijzigd door Tokkes op 01-09-2016 23:36 ]

GoTBF3 Race topic! -- Battlelog - Battalion'44 Servers :10Slots Wartide 213.32.98.194:7777 - TDM = 213.32.98.194:7781

Beste antwoord (via Tokkes op 02-09-2016 01:39)


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Euh, je doet een BeginConnect welke een asynchrone call is; deze zal (zo goed als) meteen returnen (zie dit en dit o.a.). Een time-out o.i.d. zal geraised worden in je callback (EndConnect). Je bent dan al lang voorbij 't punt dat je nog kunt "catchen" in CarbonCatsMain. Dat had je zelf waarschijnlijk ook wel gemerkt als je wat breakpoints had gezet of je debugger had gebruikt of simpelweg op regel 21 in CarbonCatsMain.cs een message had gelogged; die was dan verschenen voordat de exceptie optreedt ;) (Debuggen: Hoe doe ik dat?)

Schrijf je code eens om naar zoiets:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void ConnectToServer(IPEndPoint ip, string type, string name)
{      
    try {
        clientSock.BeginConnect(ip, new AsyncCallback(LoginToServer), clientSock);
    } catch (Exception ex) {
        mylogger.LogException("BeginConnect", ex);
    }
}

public void LoginToServer(IAsyncResult AR)
{
    try {
        clientSock.EndConnect(AR); // This statement is where it goes wrong.
    } catch (Exception ex) {
        mylogger.LogException("EndConnect", ex);
    }
}

...en verwijder de try-catch uit CarbonCatsMain.
Tokkes schreef op donderdag 01 september 2016 @ 23:26:
Heb al half StackOverflow afgezocht, tutorials gezocht, MSDN afgegaan kom ik er nog steeds niet uit.
Hoe zoek je dan in hemelsnaam :? Als je gewoon googled op "BeginConnect catch exception" is de eerste de beste hit toch al een aardig begin voor een oplossing, niet?

Als ik jou was zou ik sowieso eens kijken naar async/await (en daarbij deze post bijvoorbeeld eens goed bekijken). Async/await neemt een heleboel complexe async zaken (waaronder (correct!) afvangen van exceptions) voor rekening. Kijk ook even naar APM/EAP/TAP (waarbij die eerste twee "legacy" zijn) en de verschillen/voordelen/nadelen van elk ;)

Tot slot (maar ga hier niet mee aan de gang tenzij je bovenstaande informatie goed "meester" bent!!): er is altijd nog het UnhandledException event waarmee je in ieder geval nog altijd even 'last minute' wat zaken kunt loggen o.i.d. voordat je applicatie ermee stopt. Ga daar, alsjeblieft, niet alsnog proberen de exceptie "af te handelen", daar is het absoluut niet voor bedoeld!
johnkeates schreef op vrijdag 02 september 2016 @ 00:19:
Moet je dan niet gewoon je exceptions door blijven gooien tot de caller ze op kan vangen?
Het is een asynchrone callback; er is, zogezegd, geen caller meer. Die is al lang gevlogen / met andere dingen bezig ;)

[ Voor 82% gewijzigd door RobIII op 02-09-2016 01:02 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij

Alle reacties


Acties:
  • 0 Henk 'm!

  • Laurens-R
  • Registratie: December 2002
  • Laatst online: 29-12-2024
Wat is de exacte exception? Heb je de code al stap voor stap gedebugged? Weet je zeker dat de connecttoserver method de exception throwed? Voor hetzelfde geld, is de invoer uit de textbox niet geldig die je probeert te parsen op regel 9 van CarbonCatsMain.cs of zijn er andre regels die de exception genereren.

probeer dat eerst te achterhalen... Daar kunnen we wat meer mee :)

[ Voor 23% gewijzigd door Laurens-R op 02-09-2016 00:19 ]


Acties:
  • 0 Henk 'm!

  • johnkeates
  • Registratie: Februari 2008
  • Laatst online: 04-07 16:30
Moet je dan niet gewoon je exceptions door blijven gooien tot de caller ze op kan vangen?

Acties:
  • Beste antwoord
  • +2 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Euh, je doet een BeginConnect welke een asynchrone call is; deze zal (zo goed als) meteen returnen (zie dit en dit o.a.). Een time-out o.i.d. zal geraised worden in je callback (EndConnect). Je bent dan al lang voorbij 't punt dat je nog kunt "catchen" in CarbonCatsMain. Dat had je zelf waarschijnlijk ook wel gemerkt als je wat breakpoints had gezet of je debugger had gebruikt of simpelweg op regel 21 in CarbonCatsMain.cs een message had gelogged; die was dan verschenen voordat de exceptie optreedt ;) (Debuggen: Hoe doe ik dat?)

Schrijf je code eens om naar zoiets:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void ConnectToServer(IPEndPoint ip, string type, string name)
{      
    try {
        clientSock.BeginConnect(ip, new AsyncCallback(LoginToServer), clientSock);
    } catch (Exception ex) {
        mylogger.LogException("BeginConnect", ex);
    }
}

public void LoginToServer(IAsyncResult AR)
{
    try {
        clientSock.EndConnect(AR); // This statement is where it goes wrong.
    } catch (Exception ex) {
        mylogger.LogException("EndConnect", ex);
    }
}

...en verwijder de try-catch uit CarbonCatsMain.
Tokkes schreef op donderdag 01 september 2016 @ 23:26:
Heb al half StackOverflow afgezocht, tutorials gezocht, MSDN afgegaan kom ik er nog steeds niet uit.
Hoe zoek je dan in hemelsnaam :? Als je gewoon googled op "BeginConnect catch exception" is de eerste de beste hit toch al een aardig begin voor een oplossing, niet?

Als ik jou was zou ik sowieso eens kijken naar async/await (en daarbij deze post bijvoorbeeld eens goed bekijken). Async/await neemt een heleboel complexe async zaken (waaronder (correct!) afvangen van exceptions) voor rekening. Kijk ook even naar APM/EAP/TAP (waarbij die eerste twee "legacy" zijn) en de verschillen/voordelen/nadelen van elk ;)

Tot slot (maar ga hier niet mee aan de gang tenzij je bovenstaande informatie goed "meester" bent!!): er is altijd nog het UnhandledException event waarmee je in ieder geval nog altijd even 'last minute' wat zaken kunt loggen o.i.d. voordat je applicatie ermee stopt. Ga daar, alsjeblieft, niet alsnog proberen de exceptie "af te handelen", daar is het absoluut niet voor bedoeld!
johnkeates schreef op vrijdag 02 september 2016 @ 00:19:
Moet je dan niet gewoon je exceptions door blijven gooien tot de caller ze op kan vangen?
Het is een asynchrone callback; er is, zogezegd, geen caller meer. Die is al lang gevlogen / met andere dingen bezig ;)

[ Voor 82% gewijzigd door RobIII op 02-09-2016 01:02 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Tokkes
  • Registratie: September 2011
  • Laatst online: 12-12-2022
Laurens-R schreef op vrijdag 02 september 2016 @ 00:17:
Wat is de exacte exception? Heb je de code al stap voor stap gedebugged? Weet je zeker dat de connecttoserver method de exception throwed? Voor hetzelfde geld, is de invoer uit de textbox niet geldig die je probeert te parsen op regel 9 van CarbonCatsMain.cs of zijn er andre regels die de exception genereren.

probeer dat eerst te achterhalen... Daar kunnen we wat meer mee :)
Daar had ik inderdaad wat duidelijker kunnen zijn. Ik
Mijn invoer is wel degelijk geldig - de server is echter nog niet geimplementeerd.
De exacte exception in dit geval is een SocketException want 127.0.0.1 "actively refused connection" - dit is te verwachten.

Het is inderdaad niet de ConnectToServer die hem gooit maar de LoginToServer.
Ik had het achterwege gelaten omdat ik er niet echt problemen mee heb te achterhalen waar het fout loopt (zie de commentaar bij clientSock.EndConnect - daar wijst VS2015 aan dat het fout loopt) wel om de exacte omschrijving van de topic titel - ik kreeg mijn aanroepende class niet zover de (Socket)Exception af te vangen uit de library.
En dankzij RobIII is mij duidelijk waarom. Async calls doen wat anders als het daarop aankomt.

*kruipt in een hoekje - had nog niet geprobeerd om eens gewoon een new Exception te gooien vanuit de library, om te testen - die wordt gewoon vlotjes afgehandeld door de aanroepende WinForm*.
RobIII schreef op vrijdag 02 september 2016 @ 00:37:


Hoe zoek je dan in hemelsnaam :? Als je gewoon googled op "BeginConnect catch exception" is de eerste de beste hit toch al een aardig begin voor een oplossing, niet?
Eerlijk - ik zocht naar "Catch Exception Library c#" en gelijkaardig. Nu realiseer ik me pas hoe fout ik hiermee was. Ik was helemaal in de war omdat ik dacht het goed te doen (leek me in de eerste plaats niet heel anders dan in de voorbeelden die ik vond).
Zoals ik al aangaf is dit projectje in de eerste plaats educatief. Het gaat wel gebruikt worden door een aantal mensen maar het leek me uitdagend en veelzijdig genoeg om 1. de gelimiteerde kennis die ik heb op te frissen en 2. dingen op te steken over aspecten van programmeren die ik nog niet (voldoende) begrijp.

Je hebt me goed op weg gezet, RobIII! Waarvoor eeuwige dank! Lijkt dat ik hier goed mee op weg ga kunnen.

GoTBF3 Race topic! -- Battlelog - Battalion'44 Servers :10Slots Wartide 213.32.98.194:7777 - TDM = 213.32.98.194:7781