How to return a value when BeginInvoke is used?

G

Guest

I've successfully built several methods in my main UI thread that are called
from a separate thread. But all of them used the 'void' return type. Now
I'm trying to call a method in my main thread that will actually return a
boolean value.

Here's the basic code I've built, modelled after my earlier code:

private delegate bool IsFileOpenDelegate(string filename);
private bool IsFileOpen(string filename)
{
// if (this.InvokeRequired)
// {
// this.BeginInvoke(new IsFileOpenDelegate(IsFileOpen), new object[]
{filename});
// return;
// }

// Only reaches here when on UI thread
if (filename == "")
Debug.WriteLine("");

Debug.WriteLine("");

return true; // Debug
}


The 2nd half I haven't fleshed out yet but it's the commented out code that
I'm confused about. Two questions:

1. How do I write that BeginInvoke line so that it returns a boolean value?

2. If this method isn't touching any UI object then do I even need to use
BeginInvoke?
 
D

Dmytro Lapshyn [MVP]

Hi Robert,
1. How do I write that BeginInvoke line so that it returns a boolean
value?

BeginInvoke does not return the value. Use EndInvoke (which will block your
UI thread until the callee completes), or provide a callback delegate. I
believe MSDN Library should have detailed examples on use of asynchronous
delegates.
2. If this method isn't touching any UI object then do I even need to use
BeginInvoke?

Yes if the method does some lengthy work which is likely to block the UI
thread and thus "freeze" the whole application.

--
Sincerely,
Dmytro Lapshyn [Visual Developer - Visual C# MVP]


Robert W. said:
I've successfully built several methods in my main UI thread that are
called
from a separate thread. But all of them used the 'void' return type. Now
I'm trying to call a method in my main thread that will actually return a
boolean value.

Here's the basic code I've built, modelled after my earlier code:

private delegate bool IsFileOpenDelegate(string filename);
private bool IsFileOpen(string filename)
{
// if (this.InvokeRequired)
// {
// this.BeginInvoke(new IsFileOpenDelegate(IsFileOpen), new
object[]
{filename});
// return;
// }

// Only reaches here when on UI thread
if (filename == "")
Debug.WriteLine("");

Debug.WriteLine("");

return true; // Debug
}


The 2nd half I haven't fleshed out yet but it's the commented out code
that
I'm confused about. Two questions:

1. How do I write that BeginInvoke line so that it returns a boolean
value?

2. If this method isn't touching any UI object then do I even need to use
BeginInvoke?
 
G

Guest

Dmytro,

Thanks for your initial help. I read what you said and then studied 2 dozen
more articles. But I still can't quite get it.

Here's my new code:

private delegate bool IsFileOpenDelegate(string filename);
private bool IsFileOpen(string filename)
{
if (this.InvokeRequired)
{
IAsyncResult ar = this.BeginInvoke(new
IsFileOpenDelegate(IsFileOpen), new object[] {filename});

ar.AsyncWaitHandle.WaitOne(5000, false);

if (ar.IsCompleted)
{
this.EndInvoke(ar);

// ????????

}
}

// Only reaches here when on UI thread
return IsPollOpen(Tools.StripPathAndExtension(filename));
}



What is it that I'm failing to do?

--
Robert W.
Vancouver, BC
www.mwtech.com



Dmytro Lapshyn said:
Hi Robert,
1. How do I write that BeginInvoke line so that it returns a boolean
value?

BeginInvoke does not return the value. Use EndInvoke (which will block your
UI thread until the callee completes), or provide a callback delegate. I
believe MSDN Library should have detailed examples on use of asynchronous
delegates.
2. If this method isn't touching any UI object then do I even need to use
BeginInvoke?

Yes if the method does some lengthy work which is likely to block the UI
thread and thus "freeze" the whole application.

--
Sincerely,
Dmytro Lapshyn [Visual Developer - Visual C# MVP]


Robert W. said:
I've successfully built several methods in my main UI thread that are
called
from a separate thread. But all of them used the 'void' return type. Now
I'm trying to call a method in my main thread that will actually return a
boolean value.

Here's the basic code I've built, modelled after my earlier code:

private delegate bool IsFileOpenDelegate(string filename);
private bool IsFileOpen(string filename)
{
// if (this.InvokeRequired)
// {
// this.BeginInvoke(new IsFileOpenDelegate(IsFileOpen), new
object[]
{filename});
// return;
// }

// Only reaches here when on UI thread
if (filename == "")
Debug.WriteLine("");

Debug.WriteLine("");

return true; // Debug
}


The 2nd half I haven't fleshed out yet but it's the commented out code
that
I'm confused about. Two questions:

1. How do I write that BeginInvoke line so that it returns a boolean
value?

2. If this method isn't touching any UI object then do I even need to use
BeginInvoke?
 
G

Guest

A few minutes later . . .

Dmytro, after several hours of banging my head against the wall, trying to
find a way to make this method act like a typical function (ie. go do
something and return a value) I tried this:

private delegate bool IsFileOpenDelegate(string filename);
private bool IsFileOpen(string filename)
{
if (this.InvokeRequired)
{
return (bool) this.Invoke(new IsFileOpenDelegate(IsFileOpen), new
object[] {filename});
}

// Only reaches here when on UI thread
return IsPollOpen(Tools.StripPathAndExtension(filename));
}


It *seems* to work. As you can see, the only thing I did was change
BeginInvoke to Invoke. Yes, it's now a synchronous function, as opposed to
an asynchronous one, but by definition I think that every function is such.

If you do see anything wrong with it, please let me know though!

--
Robert W.
Vancouver, BC
www.mwtech.com



Robert W. said:
Dmytro,

Thanks for your initial help. I read what you said and then studied 2 dozen
more articles. But I still can't quite get it.

Here's my new code:

private delegate bool IsFileOpenDelegate(string filename);
private bool IsFileOpen(string filename)
{
if (this.InvokeRequired)
{
IAsyncResult ar = this.BeginInvoke(new
IsFileOpenDelegate(IsFileOpen), new object[] {filename});

ar.AsyncWaitHandle.WaitOne(5000, false);

if (ar.IsCompleted)
{
this.EndInvoke(ar);

// ????????

}
}

// Only reaches here when on UI thread
return IsPollOpen(Tools.StripPathAndExtension(filename));
}



What is it that I'm failing to do?

--
Robert W.
Vancouver, BC
www.mwtech.com



Dmytro Lapshyn said:
Hi Robert,
1. How do I write that BeginInvoke line so that it returns a boolean
value?

BeginInvoke does not return the value. Use EndInvoke (which will block your
UI thread until the callee completes), or provide a callback delegate. I
believe MSDN Library should have detailed examples on use of asynchronous
delegates.
2. If this method isn't touching any UI object then do I even need to use
BeginInvoke?

Yes if the method does some lengthy work which is likely to block the UI
thread and thus "freeze" the whole application.

--
Sincerely,
Dmytro Lapshyn [Visual Developer - Visual C# MVP]


Robert W. said:
I've successfully built several methods in my main UI thread that are
called
from a separate thread. But all of them used the 'void' return type. Now
I'm trying to call a method in my main thread that will actually return a
boolean value.

Here's the basic code I've built, modelled after my earlier code:

private delegate bool IsFileOpenDelegate(string filename);
private bool IsFileOpen(string filename)
{
// if (this.InvokeRequired)
// {
// this.BeginInvoke(new IsFileOpenDelegate(IsFileOpen), new
object[]
{filename});
// return;
// }

// Only reaches here when on UI thread
if (filename == "")
Debug.WriteLine("");

Debug.WriteLine("");

return true; // Debug
}


The 2nd half I haven't fleshed out yet but it's the commented out code
that
I'm confused about. Two questions:

1. How do I write that BeginInvoke line so that it returns a boolean
value?

2. If this method isn't touching any UI object then do I even need to use
BeginInvoke?
 
D

Dmytro Lapshyn [MVP]

Robert,

First, please understand that Control.Invoke is quite different from <some
delegate>.BeginInvoke. What Control.Invoke does is running the specified
function on the UI thread (which is the opposite to running your function on
a worker thread with BeginInvoke).

Next, looks like you are calling the same function recursively with
BeginInvoke - this is usually not needed. Let me explain it like this (I am
somewhat simplifying things, but just for the sake of understandability).

Imagine you have two threads running in parallel. One is the UI thread in
which all painting and handling user input happens. The other thread is
sleeping until delegated some work to do.

If code on the UI thread is waiting for something or does some lengthy job,
all your app becomes unresponsive. Therefore, to keep your UI alive, you
delegate all such tasks to code running on the parallel worker thread. You
do this by creating a delegate and calling BeginInvoke on it. Now that you
have called BeginInvoke, the code in the function the delegate points to
starts running in parallel.

Then you have two options. Either, when the results are needed, you call
EndInvoke on the UI thread and, in this case, you are doomed to freeze the
UI until the code running in parallel finishes its job. Or, you supply a
callback delegate which is called when the code running in parallel finishes
its job and then retrieve the return value.

In the first case, EndInvoke returns a System.Object which is *the* return
value. You just need to up-cast it to the correct type (of course the
delegate on which BeginInvoke was called must be declared as having a return
value).

In the second, you get the reference to the delegate instance from
IAsyncResult and, again, call EndInvoke. Then - see the first case.

A complete code sample is given in the "Asynchronous Delegates Programming
Sample" article in MSDN Library, ".NET Framework Developer's Guide" section.

Also, please refer to the "IAsyncResult Interface" topic in MSDN Library for
more information.

--
Sincerely,
Dmytro Lapshyn [Visual Developer - Visual C# MVP]


Robert W. said:
Dmytro,

Thanks for your initial help. I read what you said and then studied 2
dozen
more articles. But I still can't quite get it.

Here's my new code:

private delegate bool IsFileOpenDelegate(string filename);
private bool IsFileOpen(string filename)
{
if (this.InvokeRequired)
{
IAsyncResult ar = this.BeginInvoke(new
IsFileOpenDelegate(IsFileOpen), new object[] {filename});

ar.AsyncWaitHandle.WaitOne(5000, false);

if (ar.IsCompleted)
{
this.EndInvoke(ar);

// ????????

}
}

// Only reaches here when on UI thread
return IsPollOpen(Tools.StripPathAndExtension(filename));
}



What is it that I'm failing to do?

--
Robert W.
Vancouver, BC
www.mwtech.com



Dmytro Lapshyn said:
Hi Robert,
1. How do I write that BeginInvoke line so that it returns a boolean
value?

BeginInvoke does not return the value. Use EndInvoke (which will block
your
UI thread until the callee completes), or provide a callback delegate. I
believe MSDN Library should have detailed examples on use of asynchronous
delegates.
2. If this method isn't touching any UI object then do I even need to
use
BeginInvoke?

Yes if the method does some lengthy work which is likely to block the UI
thread and thus "freeze" the whole application.

--
Sincerely,
Dmytro Lapshyn [Visual Developer - Visual C# MVP]


Robert W. said:
I've successfully built several methods in my main UI thread that are
called
from a separate thread. But all of them used the 'void' return type.
Now
I'm trying to call a method in my main thread that will actually return
a
boolean value.

Here's the basic code I've built, modelled after my earlier code:

private delegate bool IsFileOpenDelegate(string filename);
private bool IsFileOpen(string filename)
{
// if (this.InvokeRequired)
// {
// this.BeginInvoke(new IsFileOpenDelegate(IsFileOpen), new
object[]
{filename});
// return;
// }

// Only reaches here when on UI thread
if (filename == "")
Debug.WriteLine("");

Debug.WriteLine("");

return true; // Debug
}


The 2nd half I haven't fleshed out yet but it's the commented out code
that
I'm confused about. Two questions:

1. How do I write that BeginInvoke line so that it returns a boolean
value?

2. If this method isn't touching any UI object then do I even need to
use
BeginInvoke?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top