How do you synchronously wait for the results of a event in C#?
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
add a comment |
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
Is there a reason why you can't just access the value which would be held in the variable? LikeocrEngine.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
add a comment |
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
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
c# multithreading events delegates
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? LikeocrEngine.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
add a comment |
Is there a reason why you can't just access the value which would be held in the variable? LikeocrEngine.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
add a comment |
1 Answer
1
active
oldest
votes
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 21 '18 at 10:17
DeejDeej
138113
138113
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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