Concepts of Programming Languages

(Sean Pound) #1
13.8 C# Threads 615

threads are more interesting than actor threads because they usually interact with
other threads and often must have their execution synchronized with other threads.
Recall from Chapter 9, that any C# method can be called indirectly through
a delegate. Such calls can be made by treating the delegate object as if it were
the name of the method. This was actually an abbreviation for a call to a del-
egate method named Invoke. So, if a delegate object’s name is chgfun1 and
the method it references takes one int parameter, we could call that method
with either of the following statements:


chgfun1(7);
chgfun1.Invoke(7);


These calls are synchronous; that is, when the method is called, the caller is
blocked until the method completes its execution. C# also supports asynchronous
calls to methods that execute in threads. When a thread is called asynchronously,
the called thread and the caller thread execute concurrently, because the caller is
not blocked during the execution of the called thread.
A thread is called asynchronously through the delegate instance method
BeginInvoke, to which are sent the parameters for the method of the del-
egate, along with two additional parameters, one of type AsyncCallback and
the other of type object. BeginInvoke returns an object that implements
the IAsyncResult interface. The delegate class also defines the EndIn-
voke instance method, which takes one parameter of type IAsyncResult
and returns the same type that is returned by the method encapsulated in the
delegate object. To call a thread asynchronously, we call it with BeginInvoke.
For now, we will use null for the last two parameters. Suppose we have the
following method declaration and thread definition:


public float MyMethod1(int x);


...
Thread myThread = new Thread(new ThreadStart(MyMethod1));


The following statement calls MyMethod asynchronously:


IAsyncResult result = myThread.BeginInvoke(10, null,
null);


The return value of the called thread is fetched with EndInvoke method,
which takes as its parameter the object (of type IAsyncResult) returned by
BeginInvoke. EndInvoke returns the return value of the called thread. For
example, to get the float result of the call to MyMethod, we would use the
following statement:


float returnValue = EndInvoke(result);


If the caller must continue some work while the called thread executes,
it must have a way to determine when the called thread is finished. For this,

Free download pdf