Me: "Son, Weed the yard, I'll read the book." ”
Scott: "Dad, I've already cleaned the yard." ”
Scott: "Dad, I've put the grass on the lawn mower." ”
Scott: Dad, the lawn mower can't start. ”
Me: "Let me start it up." ”
Scott: "Dad, I'm done." ”
This simple interaction shows the callback. I gave my son a task, and he can report the status to (repeat) interrupt me. And while I'm waiting for him to complete every part of the task, I don't have to block my own process. He can interrupt me regularly when there is an important (or event) status report, or ask me for help. A callback is an asynchronous service that provides feedback between the server and the customer. They may be in multiple threads, or they may be simple to provide a synchronized update point. In C #, a callback is represented by a delegate.
The delegate provides a type-safe callback definition. Although most delegates are used for events, this should not be the only place in the C # language that uses this functionality. At any time, if you want to communicate between two classes, and you expect less coupling than using the interface, then the delegate is the right choice for you. A delegate allows you to run a certain (callback) target and notify the user. A delegate is a reference that contains some methods. These methods can be either static or instance methods. With delegates, you can determine how to interact with one or more client objects at run time.
A multicast delegate contains all the individual function calls that are added to this delegate. There are two points to note: It is not exceptionally secure, and the return value is always the value returned after the last function call on the delegate.
Within a multicast delegate invocation, each target is successfully invoked. The delegate does not catch any exceptions, that is, any exception thrown in the delegate chain terminates the continuation call of the delegate chain.
There is also a simple problem with the return value. You can define whether the delegate has a return value or is void. You may write a callback function to detect the user's abnormal interrupts:
public delegate bool ContinueProcessing();
public void LengthyOperation( ContinueProcessing pred )
{
foreach( ComplicatedClass cl in _container )
{
cl.DoLengthyOperation();
// Check for user abort:
if (false == pred())
return;
}
}
This is working on a single delegate, but there is a problem with multicast delegates:
ContinueProcessing cp = new ContinueProcessing (
CheckWithUser );
cp += new ContinueProcessing( CheckWithSystem );
c.LengthyOperation( cp );
The value returned from the delegate's call is actually the value returned on the call to its last function. All other return values are ignored. That is, the assertion returned from Checkwithuser () is ignored.
You can manually set two delegates to call two functions. Each delegate you create contains a chain of delegates. Directly detect this chain of delegates and call each delegate yourself:
public delegate bool ContinueProcessing();
public void LengthyOperation( ContinueProcessing pred )
{
bool bContinue = true;
foreach( ComplicatedClass cl in _container )
{
cl.DoLengthyOperation();
foreach( ContinueProcessing pr in
pred.GetInvocationList( ))
bContinue &= pr ();
if (false == bContinue)
return;
}
}
At this point, I have defined the semantics of the program, so that each delegate on the delegate chain must return true after the call can continue.
Delegates provide the best way to run-time callbacks, and users simply implement the user's needs for the class. You can determine the target of the delegate at run time. You can support multiple user goals so that the user's callback can be used. NET in the implementation of the delegate.
Back to the Tutorial directory