Skip to content

Latest commit

 

History

History
62 lines (50 loc) · 2.48 KB

ii.14.6.2-synchronous-calls-to-delegates.md

File metadata and controls

62 lines (50 loc) · 2.48 KB

II.14.6.2 Synchronous calls to delegates

The synchronous mode of calling delegates corresponds to regular method calls and is performed by calling the virtual method named Invoke on the delegate. The delegate itself is the first argument to this call (it serves as the this pointer), followed by the other arguments as specified in the signature. When this call is made, the caller shall block until the called method returns. The called method shall be executed on the same thread as the caller.

[Example: Continuing the previous example, define a class Test that declares a method, onStartStop, appropriate for use as the target for the delegate.

.class public Test
{ .field public int32 MyData
  .method public void onStartStop(int32 action)
  { ret        // put your code here
  }
  .method public specialname rtspecialname
          instance void .ctor(int32 Data)
  { ret        // call base class constructor, store state, etc.
  }
}

Then define a main program. This one constructs an instance of Test and then a delegate that targets the onStartStop method of that instance. Finally, call the delegate.

.method public static void Start()
{ .maxstack 3
  .entrypoint
  .locals (class StartStopEventHandler DelegateOne,
           class Test InstanceOne)
  // Create instance of Test class
  ldc.i4.1
  newobj instance void Test::.ctor(int32)
  stloc InstanceOne 

 // Create delegate to onStartStop method of that class
 ldloc InstanceOne
  ldftn instance void Test::onStartStop(int32)
  newobj void StartStopEventHandler::.ctor(object, native int)
  stloc DelegateOne

  // Invoke the delegate, passing 100 as an argument
  ldloc DelegateOne
  ldc.i4 100
  callvirt instance void StartStopEventHandler::Invoke(int32)
  ret
}

Note that the example above creates a delegate to a non-virtual function. If onStartStop had been a virtual function, use the following code sequence instead:

ldloc InstanceOne
dup
ldvirtftn instance void Test::onStartStop(int32)
newobj void StartStopEventHandler::.ctor(object, native int)
stloc DelegateOne

// Invoke the delegate, passing 100 as an argument
ldloc DelegateOne

end example]

[Note: The code sequence above shall use dup – not ldloc InstanceOne twice. The dup code sequence is easily recognized as type-safe, whereas alternatives would require more complex analysis. Verifiability of code is discussed in Partition III end note]