callback传说, 欢迎拍砖...
History
中断 -> 函数指针(C++) -> Delegate(.Net)
Application
(1) 回调函数
call method,
代码
/// <summary>
/// 回调函数
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <returns></returns>
private bool Show_p1(int p1)
{
this.Text += p1.ToString();
return true;
}
private void button1_Click(object sender, EventArgs e)
{
InternalBiz b = new InternalBiz();
b.Test(Show_p1);
}
/// 回调函数
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <returns></returns>
private bool Show_p1(int p1)
{
this.Text += p1.ToString();
return true;
}
private void button1_Click(object sender, EventArgs e)
{
InternalBiz b = new InternalBiz();
b.Test(Show_p1);
}
代码
public delegate bool DoIt(int x);
public class InternalBiz
{
public int Test(DoIt it)
{
int[] x = {100,33,44,5,56,777,2};
//running for a long time.
for (int n = 0; n < x.Length - 1; n++)
{
Thread.Sleep(500);
it(x[n]);
}
return 0;
}
}
public class InternalBiz
{
public int Test(DoIt it)
{
int[] x = {100,33,44,5,56,777,2};
//running for a long time.
for (int n = 0; n < x.Length - 1; n++)
{
Thread.Sleep(500);
it(x[n]);
}
return 0;
}
}
(2) web application, postback by client callback (实质上是request/response信息交换而已.)
html代码
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script language="javascript">
function validate_userid() {
var id = document.getElementById("userid").value;
var message = "validate|" + id;
var context = "test1";
<%=sCallback %>
}
function delete_user() {
var id = document.getElementById("userid").value;
var message = "delete|" + id;
var context = "test1";
<%=sCallback %>
}
function processMyResult(retmsg, context) {
document.getElementById("msg_container").innerHTML = retmsg;
}
function processMyError(retmsg, context)
{
document.getElementById("msg_container").innerHTML = "<font color='red'>Error.</font>";
}
</script>
</head>
<body>
<form id="form1" runat="server">
<input id="userid" onblur="validate_userid()" />
<input type="button" onclick="delete_user()" value="Delete User" />
<div id="msg_container">
</div>
</form>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script language="javascript">
function validate_userid() {
var id = document.getElementById("userid").value;
var message = "validate|" + id;
var context = "test1";
<%=sCallback %>
}
function delete_user() {
var id = document.getElementById("userid").value;
var message = "delete|" + id;
var context = "test1";
<%=sCallback %>
}
function processMyResult(retmsg, context) {
document.getElementById("msg_container").innerHTML = retmsg;
}
function processMyError(retmsg, context)
{
document.getElementById("msg_container").innerHTML = "<font color='red'>Error.</font>";
}
</script>
</head>
<body>
<form id="form1" runat="server">
<input id="userid" onblur="validate_userid()" />
<input type="button" onclick="delete_user()" value="Delete User" />
<div id="msg_container">
</div>
</form>
</body>
</html>
C#代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page, ICallbackEventHandler
{
public string sCallback;
protected void Page_Load(object sender, EventArgs e)
{
sCallback = Page.ClientScript.GetCallbackEventReference(this,
"message", "processMyResult", "context", "processMyError", false);
}
string returnstring;
#region ICallbackEventHandler Members
public string GetCallbackResult()
{
return returnstring;
}
public void RaiseCallbackEvent(string eventArgument)
{
string method = eventArgument.Split('|')[0];
string id = eventArgument.Split('|')[1];
if (method == "validate")
{
//do validation
returnstring = "<font color='green'>Congratulations! You can use the name <font color='Red'>" + id + "</font>.</font>";
//throw new Exception();
}
else if(method == "delete")
{
//do deleting
returnstring = "success to delete <font color='Red'>" + id + "</font>.";
}
}
#endregion
}
}
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page, ICallbackEventHandler
{
public string sCallback;
protected void Page_Load(object sender, EventArgs e)
{
sCallback = Page.ClientScript.GetCallbackEventReference(this,
"message", "processMyResult", "context", "processMyError", false);
}
string returnstring;
#region ICallbackEventHandler Members
public string GetCallbackResult()
{
return returnstring;
}
public void RaiseCallbackEvent(string eventArgument)
{
string method = eventArgument.Split('|')[0];
string id = eventArgument.Split('|')[1];
if (method == "validate")
{
//do validation
returnstring = "<font color='green'>Congratulations! You can use the name <font color='Red'>" + id + "</font>.</font>";
//throw new Exception();
}
else if(method == "delete")
{
//do deleting
returnstring = "success to delete <font color='Red'>" + id + "</font>.";
}
}
#endregion
}
}
(3) and more...
WCF客户端调用服务端方法,完成后,服务端还可以“回调”客户端定义的callback方法。
WPF的绑定。采用Mode为TwoWay方式时,不仅绑定目标可以从绑定源获得数据,而且绑定目标数据发生改变时,可以引发PropertyChanged或CollectionChanged事件,也可理解为“回调”。
还有Binding时的IValueConverter,如果容许目标属性改变,则可以回调ConvertBack方法。
我们发现,似乎只要两种对象间通讯,都可以产生callback。
to be continued ...
另外,关于邮件发送的例子。邮件发送后,如果成功了,可以收到发送成功的提示,如果发送失败,同样可以收到提示的错误信息。请注意,这里的收到提示信息,只是提示信息而已,实际上为Request/Response信息交换模式而已,不是真实的callback。