none
Task.Result not working for method with out parameters RRS feed

  • Question

  • Hello,

    My Task.Result call inside a method with out parameters is not working.

    My code is:

                        try
                        {
                            System.Console.WriteLine("Calling Speech To Text service.");
                          
                            retVal = SpeechToText.GetResultAsync(strWavFileName).Result;
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }


    The exception thrown is:

    "The type initializer for 'Microsoft.CognitiveServices.Speech.Internal.carbon_csharpPINVOKE' threw an exception."

    I'm calling the sample code for the Azure Speech to Text service.

    Here is the sample code:

            public static async Task<STT_RetValues> GetResultAsync(string strFileName)
            {
                // Creates an instance of a speech config with specified subscription key and service region.
                // Replace with your own subscription key and service region (e.g., "westus").
                var config = SpeechConfig.FromSubscription("<not included>", "westus");
    
                var stopRecognition = new TaskCompletionSource<int>();
    
                var retVal = new STT_RetValues();
    
                // Creates a speech recognizer using file as audio input.
                // Replace with your own audio file name.
                using (var audioInput = AudioConfig.FromWavFileInput(strFileName))
                {
                    using (var recognizer = new SpeechRecognizer(config, audioInput))
                    {
                        // Subscribes to events.
                        recognizer.Recognizing += (s, e) =>
                        {
                            Console.WriteLine($"RECOGNIZING: Text={e.Result.Text}");
                        };
    
                        recognizer.Recognized += (s, e) =>
                        {
                            if (e.Result.Reason == ResultReason.RecognizedSpeech)
                            {
                                Console.WriteLine($"RECOGNIZED: Text={e.Result.Text}");
                                Console.WriteLine($"RECOGNIZED: Offset={e.Result.OffsetInTicks}");
                                Console.WriteLine($"RECOGNIZED: Duration={e.Result.Duration.ToString()}");
    
                                retVal = new STT_RetValues(e.Result.Text, e.Result.Duration, e.Result.OffsetInTicks);
                            }
                            else if (e.Result.Reason == ResultReason.NoMatch)
                            {
                                Console.WriteLine($"NOMATCH: Speech could not be recognized.");
                            }
                        };
    
                        recognizer.Canceled += (s, e) =>
                        {
                            Console.WriteLine($"CANCELED: Reason={e.Reason}");
    
                            if (e.Reason == CancellationReason.Error)
                            {
                                Console.WriteLine($"CANCELED: ErrorCode={e.ErrorCode}");
                                Console.WriteLine($"CANCELED: ErrorDetails={e.ErrorDetails}");
                                Console.WriteLine($"CANCELED: Did you update the subscription info?");
                            }
    
                            stopRecognition.TrySetResult(0);
                        };
    
                        recognizer.SessionStarted += (s, e) =>
                        {
                            Console.WriteLine("\n    Session started event.");
                        };
    
                        recognizer.SessionStopped += (s, e) =>
                        {
                            Console.WriteLine("\n    Session stopped event.");
                            Console.WriteLine("\nStop recognition.");
                            stopRecognition.TrySetResult(0);
                        };
    
    
                        // Starts continuous recognition. Uses StopContinuousRecognitionAsync() to stop recognition.
                        await recognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);
    
                        // Waits for completion.
                        // Use Task.WaitAny to keep the task rooted.
                        Task.WaitAny(new[] { stopRecognition.Task });
    
                        // Stops recognition.
                        await recognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);
                    }
                }
    
                return retVal;
            }
        }

    Any suggestions?


    williamj

    Tuesday, December 11, 2018 8:20 PM

Answers

  • Yes and no. Firstly that code won't compile because out parameters must be definitely assigned before the function returns. I assume that you have code after the try-catch that is doing that?

    The try-catch is redundant since you're just rethrowing the exception. But the call to the async method is correct. You make the call and then use Result to get the response. This will block the calling thread. If the task throws an exception then it will be thrown at this point.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by williamj8 Thursday, December 13, 2018 8:45 PM
    Thursday, December 13, 2018 8:06 PM
    Moderator

All replies

  • Hi williamj8,

    Thank you for posting here.

    >>My Task.Result call inside a method with out parameters is not working.

    For your question, what does the out parameter mean? I do not see any out parameter in your code.

    Please check the suggestion in the link below. To set the x86 or x64 platform.

    https://stackoverflow.com/questions/51414593/the-type-initializer-for-microsoft-cognitiveservices-speech-internal-carbon-csh

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, December 12, 2018 6:25 AM
    Moderator
  • Wendy:

    The caller methods parameters are:

           public void Correct(string strText, string strVOBFile, string strMovieSegment, string strBegTS, string strEndTS, string strOutputFile, string strLogFileBegTS, string strLogFileEndTS, int iThreadNumber, out string strNewBegTS, out string strNewEndTS, out bool bModified, out string strDebug)
            {

    And, all dlls for the project are x86.

    I stepped through the app with a debugger, and noticed that the error is thrown on the SpeechConfig.FromSubscription call.

    However, I am able to call the Speech To Text service code from its own project.

    Thanks.

     


    williamj

    Wednesday, December 12, 2018 5:02 PM
  • You cannot use await with out/ref parameters because they don't work. The caller returns (potentially) before the task completes so out/ref parameters don't make sense. The reason I bring this up is because you posted an async method and it didn't have the out parameters like you mentioned. Nowhere in that method do I see the call you said you were having an issue with.

    Please post the exact method that has the out parameter. I assume it contains the task code you said wasn't working. If it doesn't then what does the task code you posted have to do with the out parameter issue.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, December 13, 2018 6:38 PM
    Moderator
  • Mr. Taylor:

    Thanks for your reply.

    Here is the method that calls the async method:

           public void Correct(string strText, string strVOBFile, string strMovieSegment, string strBegTS, string strEndTS, string strOutputFile, string strLogFileBegTS, string strLogFileEndTS, int iThreadNumber, out string strNewBegTS, out string strNewEndTS, out bool bModified, out string strDebug)
            {
    
    ...
                      try
                        {
                            System.Console.WriteLine("Calling Speech To Text service.");
                            
                            retVal = SpeechToText.GetResultAsync(strWavFileName).Result;
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
    
    ...
    
    }

    Is this a correct call to the async method?

    Thanks.


    williamj




    • Edited by williamj8 Thursday, December 13, 2018 7:58 PM
    Thursday, December 13, 2018 7:56 PM
  • Yes and no. Firstly that code won't compile because out parameters must be definitely assigned before the function returns. I assume that you have code after the try-catch that is doing that?

    The try-catch is redundant since you're just rethrowing the exception. But the call to the async method is correct. You make the call and then use Result to get the response. This will block the calling thread. If the task throws an exception then it will be thrown at this point.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by williamj8 Thursday, December 13, 2018 8:45 PM
    Thursday, December 13, 2018 8:06 PM
    Moderator
  • Mr. Taylor:

    Thanks for your reply.

    I removed the code that addresses your recommendations.

    The SpeechToText.GetResultAsync throws an exception, I am not sure why.

    The exception is: "The type initializer for 'Microsoft.CognitiveServices.Speech.Internal.carbon_csharpPINVOKE'"

    with a stack trace of:

       at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
       at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
       at System.Threading.Tasks.Task`1.get_Result() 

       at VOBSegmentCorrector.SegmentCorrector.Correct(String strText, String strVOBFile, String strMovieSegment, String strBegTS, String strEndTS, String strOutputFile, String strLogFileBegTS, String strLogFileEndTS, Int32 iThreadNumber, String& strNewBegTS, String& strNewEndTS, Boolean& bModified, String& strDebug) in E:\Users\William Johnston\Documents\Visual Studio 2010\Projects\Visual Studio Projects\DVDXMLWriter\VOBSegmentCorrector\SegmentCorrector.cs:line 20

    What do you think?


    williamj

    Thursday, December 13, 2018 8:32 PM
  • A type initializer exception means a type has a static constructor and/or static fields and the type (when it is first referenced) is throwing an exception while initializing the fields or calling the constructor. This would be unrelated to the asyn call.

    The carbon_csharpPINVOKE type (?) is having the issue. Take a look at its static ctor and/or static field initializers. One of these is having an issue. The exception that is thrown should have the InnerException property set. The inner exception will generally contain the actual error that occurred but you may need to drop down a couple of levels to find the actual error.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, December 13, 2018 8:38 PM
    Moderator
  • Mr. Taylor:

    I found the error.

    I wasn't including the Microsoft Cognitive Services Speech NuGet package in the other projects.

    Thank you.

     


    williamj

    Thursday, December 13, 2018 8:44 PM