对 Delegate的误用及解决办法
在开发Silverligh程式的时候,发现了一个问题。
先看一段代码:目的很简单,就是在执行查询的时候进行异步处理。

public partial class test : UserControl
{
ISDApp01Xml.SDApp01XmlSoapClient client = new ISDApp01Xml.SDApp01XmlSoapClient();
public test()
{
InitializeComponent();
}
private void btnQuery_Click( object sender, RoutedEventArgs e)
{
string sql = " select id,name,parentid,grade from pdm_basic_info " ;
client.ExecuteQueryCompleted += client_ExecuteQueryCompleted;
client.ExecuteQueryAsync(sql);
}
void client_ExecuteQueryCompleted( object sender, NewWordsDemo.ISDApp01Xml.ExecuteQueryCompletedEventArgs e)
{
if (e.Error == null )
{
dgshow.ItemsSource = from item in e.Result.Descendants( " row " )
select new BasicInfo
{
id = item.Attribute( " ID " ).Value.ToString(),
name = item.Attribute( " NAME " ).Value.ToString(),
parentid = item.Attribute( " PARENTID " ).Value.ToString(),
grade = item.Attribute( " GRADE " ).Value.ToString(),
};
MessageBox.Show( " Done

}
else
{
MessageBox.Show( " Error " );
}
}
}
public class BasicInfo
{
public string id { set ; get ; }
public string name { set ; get ; }
public string parentid { set ; get ; }
public string grade { set ; get ; }
}
结果发现:在执行第n次查询的时候 MessageBox.Show("Done...");会执行n次.
原因:这里定义了一个公有的
ISDApp01Xml.SDApp01XmlSoapClient client = new ISDApp01Xml.SDApp01XmlSoapClient();而后在查询动作时候,为ExecuteQueryCompleted事件添加执 行方法,注意到这里用的是典型的多播委托的方式“+=”,也就是说,每执行一次查询,就为此事件添加一个同样的执行方法,从而造成在执行第n次查询的时 候,实际上方法执行了n次。
解决:
(1)把service进行私有实例化:在用到的时候再进行实例化,出了作用域,自动“释放”。
(2)service公有,单是委托方法只能加载一次.
1.

private void btnQuery_Click( object sender, RoutedEventArgs e)
{
string sql = " select id,name,parentid,grade from pdm_basic_info " ;
ISDApp01Xml.SDApp01XmlSoapClient client = new ISDApp01Xml.SDApp01XmlSoapClient();
client.ExecuteQueryCompleted += client_ExecuteQueryCompleted;
client.ExecuteQueryAsync(sql);
}
2.
public partial class test : UserControl
{
ISDApp01Xml.SDApp01XmlSoapClient client = new ISDApp01Xml.SDApp01XmlSoapClient();
public test()
{
InitializeComponent();
}
private void btnQuery_Click( object sender, RoutedEventArgs e)
{
string sql = " select id,name,parentid,grade from pdm_basic_info " ;
client.ExecuteQueryAsync(sql);
}
void client_ExecuteQueryCompleted( object sender, NewWordsDemo.ISDApp01Xml.ExecuteQueryCompletedEventArgs e)
{
if (e.Error == null )
{
dgshow.ItemsSource = from item in e.Result.Descendants( " row " )
select new BasicInfo
{
id = item.Attribute( " ID " ).Value.ToString(),
name = item.Attribute( " NAME " ).Value.ToString(),
parentid = item.Attribute( " PARENTID " ).Value.ToString(),
grade = item.Attribute( " GRADE " ).Value.ToString(),
};
MessageBox.Show( " Done " );
}
else
{
MessageBox.Show( " Error " );
}
}
private void UserControl_Loaded( object sender, RoutedEventArgs e)
{
client.ExecuteQueryCompleted += client_ExecuteQueryCompleted;
}
}