How do you synchronously wait for the results of a event in C#?












0















There seems to be a pattern in Windows Applications in C# whereby you assign a 'handler' to an Event, and this Event is fired as a side-effect of a seperate method call. To give an example



ocrEngine = new OcrEngine();
ocrEngine.OcrResults += new OcrResultsEventHandler(ocrEngine_MethodThatProcessesTheResultsOfOcr);


So, for example, you have an OCR (Optical character recognition) engine and you want to pass it an image, and get back some text. However, in this API I am using the method to pass in the image return an int. i.e.



int result = ocEngine.ReadImage(image);


This means I discover if the OCR process was successful with an int, i.e 0 = success.
However the actual results are returned in the 'ocrEngine_MethodThatProcessesTheResultsOfOcr' method.



If I am running this from a console app, I am trying to understand the pattern I should be using to return the data, as effectively there is no obvious synchronous way of returning the actual result.
In fact there are clearly at least two threads running per method call to ocEngine.ReadImage(image);
I have a work around involving Thread.Sleep and checking for a boolean, but this seems plain wrong.



Any guidance would be greatly appreciated.










share|improve this question























  • Is there a reason why you can't just access the value which would be held in the variable? Like ocrEngine.theResultOfRead()?

    – Frontear
    Nov 19 '18 at 17:49











  • You could wait on an AutoResetEvent right after calling ReadImage, and set the AutoResetEvent in the event handler. Although this doesn't deal with errors such as timeout.

    – Jon
    Nov 19 '18 at 17:53











  • The most direct way is to use a synchronization mechanism like ManulResetEventSlim. The main thread will call Wait for the callback to call Set. Alternatively you can use TaskCompletionSource to create a task-based async API.

    – Mike Zboray
    Nov 19 '18 at 17:57
















0















There seems to be a pattern in Windows Applications in C# whereby you assign a 'handler' to an Event, and this Event is fired as a side-effect of a seperate method call. To give an example



ocrEngine = new OcrEngine();
ocrEngine.OcrResults += new OcrResultsEventHandler(ocrEngine_MethodThatProcessesTheResultsOfOcr);


So, for example, you have an OCR (Optical character recognition) engine and you want to pass it an image, and get back some text. However, in this API I am using the method to pass in the image return an int. i.e.



int result = ocEngine.ReadImage(image);


This means I discover if the OCR process was successful with an int, i.e 0 = success.
However the actual results are returned in the 'ocrEngine_MethodThatProcessesTheResultsOfOcr' method.



If I am running this from a console app, I am trying to understand the pattern I should be using to return the data, as effectively there is no obvious synchronous way of returning the actual result.
In fact there are clearly at least two threads running per method call to ocEngine.ReadImage(image);
I have a work around involving Thread.Sleep and checking for a boolean, but this seems plain wrong.



Any guidance would be greatly appreciated.










share|improve this question























  • Is there a reason why you can't just access the value which would be held in the variable? Like ocrEngine.theResultOfRead()?

    – Frontear
    Nov 19 '18 at 17:49











  • You could wait on an AutoResetEvent right after calling ReadImage, and set the AutoResetEvent in the event handler. Although this doesn't deal with errors such as timeout.

    – Jon
    Nov 19 '18 at 17:53











  • The most direct way is to use a synchronization mechanism like ManulResetEventSlim. The main thread will call Wait for the callback to call Set. Alternatively you can use TaskCompletionSource to create a task-based async API.

    – Mike Zboray
    Nov 19 '18 at 17:57














0












0








0








There seems to be a pattern in Windows Applications in C# whereby you assign a 'handler' to an Event, and this Event is fired as a side-effect of a seperate method call. To give an example



ocrEngine = new OcrEngine();
ocrEngine.OcrResults += new OcrResultsEventHandler(ocrEngine_MethodThatProcessesTheResultsOfOcr);


So, for example, you have an OCR (Optical character recognition) engine and you want to pass it an image, and get back some text. However, in this API I am using the method to pass in the image return an int. i.e.



int result = ocEngine.ReadImage(image);


This means I discover if the OCR process was successful with an int, i.e 0 = success.
However the actual results are returned in the 'ocrEngine_MethodThatProcessesTheResultsOfOcr' method.



If I am running this from a console app, I am trying to understand the pattern I should be using to return the data, as effectively there is no obvious synchronous way of returning the actual result.
In fact there are clearly at least two threads running per method call to ocEngine.ReadImage(image);
I have a work around involving Thread.Sleep and checking for a boolean, but this seems plain wrong.



Any guidance would be greatly appreciated.










share|improve this question














There seems to be a pattern in Windows Applications in C# whereby you assign a 'handler' to an Event, and this Event is fired as a side-effect of a seperate method call. To give an example



ocrEngine = new OcrEngine();
ocrEngine.OcrResults += new OcrResultsEventHandler(ocrEngine_MethodThatProcessesTheResultsOfOcr);


So, for example, you have an OCR (Optical character recognition) engine and you want to pass it an image, and get back some text. However, in this API I am using the method to pass in the image return an int. i.e.



int result = ocEngine.ReadImage(image);


This means I discover if the OCR process was successful with an int, i.e 0 = success.
However the actual results are returned in the 'ocrEngine_MethodThatProcessesTheResultsOfOcr' method.



If I am running this from a console app, I am trying to understand the pattern I should be using to return the data, as effectively there is no obvious synchronous way of returning the actual result.
In fact there are clearly at least two threads running per method call to ocEngine.ReadImage(image);
I have a work around involving Thread.Sleep and checking for a boolean, but this seems plain wrong.



Any guidance would be greatly appreciated.







c# multithreading events delegates






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 '18 at 17:35









DeejDeej

138113




138113













  • Is there a reason why you can't just access the value which would be held in the variable? Like ocrEngine.theResultOfRead()?

    – Frontear
    Nov 19 '18 at 17:49











  • You could wait on an AutoResetEvent right after calling ReadImage, and set the AutoResetEvent in the event handler. Although this doesn't deal with errors such as timeout.

    – Jon
    Nov 19 '18 at 17:53











  • The most direct way is to use a synchronization mechanism like ManulResetEventSlim. The main thread will call Wait for the callback to call Set. Alternatively you can use TaskCompletionSource to create a task-based async API.

    – Mike Zboray
    Nov 19 '18 at 17:57



















  • Is there a reason why you can't just access the value which would be held in the variable? Like ocrEngine.theResultOfRead()?

    – Frontear
    Nov 19 '18 at 17:49











  • You could wait on an AutoResetEvent right after calling ReadImage, and set the AutoResetEvent in the event handler. Although this doesn't deal with errors such as timeout.

    – Jon
    Nov 19 '18 at 17:53











  • The most direct way is to use a synchronization mechanism like ManulResetEventSlim. The main thread will call Wait for the callback to call Set. Alternatively you can use TaskCompletionSource to create a task-based async API.

    – Mike Zboray
    Nov 19 '18 at 17:57

















Is there a reason why you can't just access the value which would be held in the variable? Like ocrEngine.theResultOfRead()?

– Frontear
Nov 19 '18 at 17:49





Is there a reason why you can't just access the value which would be held in the variable? Like ocrEngine.theResultOfRead()?

– Frontear
Nov 19 '18 at 17:49













You could wait on an AutoResetEvent right after calling ReadImage, and set the AutoResetEvent in the event handler. Although this doesn't deal with errors such as timeout.

– Jon
Nov 19 '18 at 17:53





You could wait on an AutoResetEvent right after calling ReadImage, and set the AutoResetEvent in the event handler. Although this doesn't deal with errors such as timeout.

– Jon
Nov 19 '18 at 17:53













The most direct way is to use a synchronization mechanism like ManulResetEventSlim. The main thread will call Wait for the callback to call Set. Alternatively you can use TaskCompletionSource to create a task-based async API.

– Mike Zboray
Nov 19 '18 at 17:57





The most direct way is to use a synchronization mechanism like ManulResetEventSlim. The main thread will call Wait for the callback to call Set. Alternatively you can use TaskCompletionSource to create a task-based async API.

– Mike Zboray
Nov 19 '18 at 17:57












1 Answer
1






active

oldest

votes


















0














It seems as though there is no perfect answer here, other than using an API that instead returns the results in a syncronous manner.
The best approach that has been suggested was as follows:



static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
public static string Process(Bitmap image)
{
...
int result = ocEngine.ReadImage(image);
autoResetEvent.WaitOne(2500);
...
}


then in the callback event call:



autoResetEvent.Set();


once the work has been done.



This approach produced more consistent results, however, and this may have been the result of the API we were using, still caused timeout/deadlock issues occasionally.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53379935%2fhow-do-you-synchronously-wait-for-the-results-of-a-event-in-c%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    It seems as though there is no perfect answer here, other than using an API that instead returns the results in a syncronous manner.
    The best approach that has been suggested was as follows:



    static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
    public static string Process(Bitmap image)
    {
    ...
    int result = ocEngine.ReadImage(image);
    autoResetEvent.WaitOne(2500);
    ...
    }


    then in the callback event call:



    autoResetEvent.Set();


    once the work has been done.



    This approach produced more consistent results, however, and this may have been the result of the API we were using, still caused timeout/deadlock issues occasionally.






    share|improve this answer




























      0














      It seems as though there is no perfect answer here, other than using an API that instead returns the results in a syncronous manner.
      The best approach that has been suggested was as follows:



      static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
      public static string Process(Bitmap image)
      {
      ...
      int result = ocEngine.ReadImage(image);
      autoResetEvent.WaitOne(2500);
      ...
      }


      then in the callback event call:



      autoResetEvent.Set();


      once the work has been done.



      This approach produced more consistent results, however, and this may have been the result of the API we were using, still caused timeout/deadlock issues occasionally.






      share|improve this answer


























        0












        0








        0







        It seems as though there is no perfect answer here, other than using an API that instead returns the results in a syncronous manner.
        The best approach that has been suggested was as follows:



        static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
        public static string Process(Bitmap image)
        {
        ...
        int result = ocEngine.ReadImage(image);
        autoResetEvent.WaitOne(2500);
        ...
        }


        then in the callback event call:



        autoResetEvent.Set();


        once the work has been done.



        This approach produced more consistent results, however, and this may have been the result of the API we were using, still caused timeout/deadlock issues occasionally.






        share|improve this answer













        It seems as though there is no perfect answer here, other than using an API that instead returns the results in a syncronous manner.
        The best approach that has been suggested was as follows:



        static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
        public static string Process(Bitmap image)
        {
        ...
        int result = ocEngine.ReadImage(image);
        autoResetEvent.WaitOne(2500);
        ...
        }


        then in the callback event call:



        autoResetEvent.Set();


        once the work has been done.



        This approach produced more consistent results, however, and this may have been the result of the API we were using, still caused timeout/deadlock issues occasionally.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 21 '18 at 10:17









        DeejDeej

        138113




        138113
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53379935%2fhow-do-you-synchronously-wait-for-the-results-of-a-event-in-c%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()