0

I don't what it is, but the moment I run my project in debug mode and hits this line within PingServerAsync():

 var response = await httpClient.PostAsJsonAsync(url, payload);

it hangs for a sec, then just exists out with no response value. It's NOT hitting my Exception, nor is it logging the response.

public async Task CheckDicomServersAsync(string hostName)
    {
         ...
         var cstore = result.FirstOrDefault();
         MqttService.applog.Debug($"****** Gonna Dicom Echo this - {cstore.ClientAETitle} *******");
        string resp = await **PingDicomServerAsync**(cstore);
        Console.WriteLine($"Dicom Echo response: {resp}");
   }

private async Task<string> PingServerAsync(DICOMClient client)
    {

        EchoViewModelSettings payload = new EchoViewModelSettings();
        payload.ClientAE = client.ClientAETitle;
        // more props here..            
       
        using (httpClient)
        {
            httpClient.BaseAddress = new Uri(m_appConfig.DICOM_URL);
           
            var requestUri = handler + "/Echo?SessionID=" + System.Web.HttpUtility.UrlEncode(session.SessionID.ToString());

            try
            {
                MqttService.applog.Debug($"Make request: {requestUri}");

                var url = "http://localhost/MyDicomAPI/api/dicom/Echo?SessionID=my_session";

                // *** FIRE POST HERE ***
                var response = await httpClient.PostAsJsonAsync(url, payload);                    

                MqttService.applog.Debug($"The Response: {response.Content}");

                if (response.IsSuccessStatusCode)
                {
                    var echoResponse = await response.Content.ReadAsStringAsync();
                    MqttService.applog.Debug($"The Echo Response is: {echoResponse}");
                }                    
                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    Console.WriteLine(response.StatusCode.ToString());
                    return response.StatusCode.ToString();
                }
                else
                {
                    return response.StatusCode.ToString();
                }
            }
            catch (Exception ex)
            {
                MqttService.applog.Error($"WTF is wrong now: {ex}");
                throw;
            }
            
            
        }
    }

Also checking this video tutorial as a reference - https://www.youtube.com/watch?v=VSAlIE2SFHw

Postman returns a response (value zero is success here) for the same URL and Json body:

enter image description here

*** UPDATE - Showing the calls from the beginning of Program.cs (i.e. temp bypass the Win Service) ***

 // **Program.cs**
 static void Main()
    {
        //ServiceBase[] ServicesToRun;
        //ServicesToRun = new ServiceBase[]
        //{
        //    new MqttService()
        //};
        //ServiceBase.Run(ServicesToRun);

        MqttService mqttSvc = new MqttService(); // debug version
        
        mqttSvc.**StartDebugMode**();
    }

    // **MqttService.cs**
    public void **StartDebugMode**()
    {
        Init();

        this.**CheckOtherServers**(hostName);

        //StartSubscriber();
        //StartPublisher();
        //PublishHeartBeat(null, null);            
    }

    private async void **CheckOtherServers**(string hostName)
    {
        if (this.pingDicom)
        {
            DicomStatus dicom = new DicomStatus();
            **await dicom.CheckDicomServersAsync(hostName);**
        }
    }
asportnoy
  • 2,218
  • 2
  • 17
  • 31
bob.mazzo
  • 5,183
  • 23
  • 80
  • 149
  • What invokes PingServerAsync? – mason Mar 17 '23 at 20:10
  • @mason this line here in the caller, `string resp = await PingDicomServerAsync(cstore);` - and it DOES indeed make the call, however it's NOT returning. I'll update my post to show the call. – bob.mazzo Mar 17 '23 at 20:21
  • Okay - but how is the code that calls that invoked? My thinking here is that you've reached a deadlock situation, but we need to see back up the stack trace to understand how this ultimately happens. – mason Mar 17 '23 at 20:22
  • What does that mean, your "debug" version? Please show the trace of calls from your main method all the way to PingServerAsync – mason Mar 17 '23 at 20:27
  • @mason - I've updated some code at the bottom of my origin post to show the flow from Program.cs. Thank you. – bob.mazzo Mar 17 '23 at 20:51
  • @mason - You were onto something ! I went back to letting the Windows Service run, and used the `Debug\AttachToProcess` option in `VS2019`. Turns out that the httpClient request works ! I don't understand why an `await` causes problems if I'm treating like a console program. I'm missing something... – bob.mazzo Mar 17 '23 at 22:12
  • 1
    You did async void. That's one of the unforgettable sins a C# developer can make. It's fire-and-forget and almost always the wrong thing to use. See this video. https://youtu.be/lQu-eBIIh-w – mason Mar 17 '23 at 23:28
  • PostAsJsonAsync doesn't work properly in many cases. What is your problme. Why don't use PostAsync instead? – Serge Mar 20 '23 at 02:48
  • @Serge What do you mean it "doesn't work properly in many cases" - what cases are you talking about? – mason Mar 20 '23 at 13:06
  • @mason for my experience it didn't work properly in the most cases. I just advise you to use PostAsync – Serge Mar 20 '23 at 13:10
  • @Serge If you're having trouble using PostAsJsonAsync, feel free to create a [mcve] and ask your own question. There's no need to tell other people to use a perfectly valid piece of the framework just because you've personally had trouble using it in the past. Especially if you're going to be so vague as to not provide any sort of concrete example. – mason Mar 20 '23 at 13:15
  • @mason I don't care about anything if there a work around. This is my point, that people should not bother another people with the questions if there is another way. And there are alrealy plenty of trollies here, we don't need another one. – Serge Mar 20 '23 at 13:19
  • @mason - not having extensive experience with modern c# techniques, I didn't realize that async void was a no-go. This is a great learning experience. Please post it as an answer, as you have spent considerable time investing my post. Much appreciated. – bob.mazzo Mar 20 '23 at 13:48
  • 1
    @bob.mazzo Stephen Cleary literally [wrote the book on the subject](https://www.amazon.com/Concurrency-Cookbook-Asynchronous-Multithreaded-Programming/dp/1449367569/ref=sr_1_2?crid=1EVZYQZ6V00GU&keywords=stephen+cleary&qid=1679320760&sprefix=stephen+cleary%2Caps%2C119&sr=8-2), and his answer covers everything I said. – mason Mar 20 '23 at 14:00

1 Answers1

1

In general, you should avoid async void. One of the problems with async void is that the calling code doesn't know when the task completes. So your Main method just keeps on running until it reaches the end, at which point it exits Main, which exits your application.

Use async Task instead of async void and await the task. On modern runtimes (i.e., .NET Core), you can have an async Task Main; on older platforms like the one you're targeting, you'll have to have Main block on the returned task instead of awaiting it. I.e., mqttSvc.StartDebugMode().GetAwaiter().GetResult().

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810