最近做一个项目,用WebService做一个数据库查询,查询需要对多个数据库执行查询,我在主程序中使用多个线程分别来各自和一个数据库建立连接,执行完成后将结果放入一个公共变量。现在有一个问题是数据库查询的结果由于网络原因会有快慢之分,为了缩短相应我在主程序中设置了一个时间值一旦超出该时间值主程序就会把已经得到的结果返回不再等待执行较慢的线程,执行较慢的线程如果没有将结果放入公共变量执行完成后会把数据放入缓冲区,下次执行时就不必再建立连接了。
但是现在的问题是主程序在执行了返回(return)后程序就结束了,子线程这时候显然会由于主程序的结束而产生异常,无法将结果正常放入缓冲区。有没有办法可以解决。期待高手指点一二!
但是现在的问题是主程序在执行了返回(return)后程序就结束了,子线程这时候显然会由于主程序的结束而产生异常,无法将结果正常放入缓冲区。有没有办法可以解决。期待高手指点一二!
后台的就是主程序完成后,子线程还会继续运行的,直到完成。具体的属性设置是:IsBackground
这句话是错误的,后台线程不会阻止进程退出,只要进程退出了,后台线程自动终止;而前台线程才会阻止进程退出!
类型 System.ComponentModel.ISite 的成员 System.ComponentModel.MarshalByValueComponent.Site 是接口,因此无法将其序列化。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 异常详细信息: System.NotSupportedException: 类型 System.ComponentModel.ISite 的成员 System.ComponentModel.MarshalByValueComponent.Site 是接口,因此无法将其序列化。源错误: 执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。 堆栈跟踪:
[NotSupportedException: 类型 System.ComponentModel.ISite 的成员 System.ComponentModel.MarshalByValueComponent.Site 是接口,因此无法将其序列化。]
System.Xml.Serialization.TypeScope.ImportTypeDesc(Type type, Boolean canBePrimitive, MemberInfo memberInfo) +1283
System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference) +50
System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo propertyInfo) +54
System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo memberInfo) +88
System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns) +1536
System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns) +662
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, Boolean repeats) +440[InvalidOperationException: 反射类型“System.Data.DataTable”时出错。]
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, Boolean repeats) +1059
System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType) +8238
System.Xml.Serialization.XmlReflectionImporter.ImportMemberMapping(XmlReflectionMember xmlReflectionMember, String ns, XmlReflectionMember[] xmlReflectionMembers) +795
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement) +300[InvalidOperationException: 反射“GetDTResult”时出错。]
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(XmlReflectionMember[] xmlReflectionMembers, String ns, Boolean hasWrapperElement) +607
System.Xml.Serialization.XmlReflectionImporter.ImportMembersMapping(String elementName, String ns, XmlReflectionMember[] members, Boolean hasWrapperElement) +108
System.Web.Services.Protocols.SoapReflector.ImportMembersMapping(XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, Boolean serviceDefaultIsEncoded, Boolean rpc, SoapBindingUse use, SoapParameterStyle paramStyle, String elementName, String elementNamespace, Boolean nsIsDefault, XmlReflectionMember[] members, Boolean validate) +169
System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo, Boolean client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, String defaultNs) +2860[InvalidOperationException: 无法反射方法 ThreadTest.GetDT。]
System.Web.Services.Protocols.SoapReflector.ReflectMethod(LogicalMethodInfo methodInfo, Boolean client, XmlReflectionImporter xmlImporter, SoapReflectionImporter soapImporter, String defaultNs) +5415
System.Web.Services.Description.SoapProtocolReflector.ReflectMethod() +130
System.Web.Services.Description.ProtocolReflector.ReflectBinding(ReflectedBinding reflectedBinding) +1818
System.Web.Services.Description.ProtocolReflector.Reflect() +506
System.Web.Services.Description.ServiceDescriptionReflector.ReflectInternal(ProtocolReflector[] reflectors) +495
System.Web.Services.Description.ServiceDescriptionReflector.Reflect(Type type, String url) +112
System.Web.Services.Protocols.DocumentationServerType..ctor(Type type, String uri) +158
System.Web.Services.Protocols.DocumentationServerProtocol.Initialize() +269
System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) +106[InvalidOperationException: 无法处理请求。]
System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing) +205
System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +82[InvalidOperationException: 未能处理请求。]
System.Web.Services.Protocols.WebServiceHandlerFactory.CoreGetHandler(Type type, HttpContext context, HttpRequest request, HttpResponse response) +154
System.Web.Services.Protocols.WebServiceHandlerFactory.GetHandler(HttpContext context, String verb, String url, String filePath) +94
System.Web.HttpApplication.MapHttpHandler(HttpContext context, String requestType, String path, String pathTranslated, Boolean useAppConfig) +699
System.Web.MapHandlerExecutionStep.System.Web.HttpApplication+IExecutionStep.Execute() +95
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +173
{
DataTable PubTable = null;
int FinishNum = 0;
bool Lock = false;
bool DataOK = false;
Cache DBCache = new Cache();
public DataTable GetDate()
{
ThreadStart TS = new ThreadStart(GetDBTable);
Thread T1 = new Thread(TS);
T1.Name = "Thread1";
T1.Start();
Thread T2 = new Thread(TS);
T2.Name = "Thread2";
T2.Start();
Thread.Sleep(500);
DataOK = true;
DataTable Dt = PubTable;
if(FinishNum<2&&Lock)Thread.Sleep(100);
return Dt;
}
public viod GetDBTable()
{
...
}
...
}
ds.Tables.Add(Dt);
return ds;
可能要改为
while (FinishNum<2&&Lock)Thread.Sleep(100);还是那句话:return不会引起线程中止的
{
public int i=0;
public DataSet Ds = new DataSet();
SqlConnection Conn = new SqlConnection("Server=;UID=sa;PWD=;");
private void Page_Load(object sender, System.EventArgs e)
{
// 在此处放置用户代码以初始化页面
ThreadStart Ts = new ThreadStart(Th);
Thread T1 = new Thread(Ts);
T1.Name = "Thread1";
T1.Start();
Thread T2 = new Thread(Ts);
T2.Name = "Thread2";
T2.Start();
Thread.Sleep(5000);
if(Ds.Tables.Count>0)
{
DataTable Dt = Ds.Tables[0];
for(int i=0;i<Dt.Rows.Count;i++)
{
DataRow Dr = Dt.Rows[i];
Response.Write(Dr[0] + " " + Dr[1] + " " + Dr[2]);
}
}
//Response.Write(i.ToString());
Response.End(); }
private void Th()
{
//Response.Write(Thread.CurrentThread.Name + ":" + i);
Conn.Open();
SqlDataAdapter Sda = new SqlDataAdapter("Select [ID],[UserName],UserLable From [User]",Conn);
DataSet DsT = new DataSet();
Sda.Fill(DsT);
Conn.Close();
Ds.Tables.Add(DsT.Tables[0].Clone());
if(Ds.Tables.Count>0)
{
DataTable Dt = Ds.Tables[0];
for(int i=0;i<Dt.Rows.Count;i++)
{
DataRow Dr = Dt.Rows[i];
Response.Write(Dr[0] + " " + Dr[1] + " " + Dr[2]);
}
}
Sda.Dispose();
}
}
得到的结果是空的
private void Th()
{
//Response.Write(Thread.CurrentThread.Name + ":" + i);
Conn.Open();
SqlDataAdapter Sda = new SqlDataAdapter("Select UB_User_ID,UB_User_Name,UB_User_Lable From UserBasic",Conn);
DataSet DsT = new DataSet();
Response.Write(Thread.CurrentThread.Name);
Sda.Fill(DsT);
Conn.Close();
Ds.Tables.Add(DsT.Tables[0].Clone());
if(DsT.Tables.Count>0)
{
DataTable Dt = DsT.Tables[0];
for(int i=0;i<Dt.Rows.Count;i++)
{
DataRow Dr = Dt.Rows[i];
Response.Write(Dr[0] + " " + Dr[1] + " " + Dr[2]);
}
}
Sda.Dispose();
}
但是当我把Response.Write(Thread.CurrentThread.Name);放到Sda.Fill(DsT);后面面就什么也没有了详细代码如下:
private void Th()
{
//Response.Write(Thread.CurrentThread.Name + ":" + i);
Conn.Open();
SqlDataAdapter Sda = new SqlDataAdapter("Select UB_User_ID,UB_User_Name,UB_User_Lable From UserBasic",Conn);
DataSet DsT = new DataSet();
Sda.Fill(DsT);
Response.Write(Thread.CurrentThread.Name);
Conn.Close();
Ds.Tables.Add(DsT.Tables[0].Clone());
if(DsT.Tables.Count>0)
{
DataTable Dt = DsT.Tables[0];
for(int i=0;i<Dt.Rows.Count;i++)
{
DataRow Dr = Dt.Rows[i];
Response.Write(Dr[0] + " " + Dr[1] + " " + Dr[2]);
}
}
Sda.Dispose();
}
Clone只复制结构,不复制DataRow
private void Th()
{
//Response.Write(Thread.CurrentThread.Name + ":" + i);
SqlConnection Conn = new SqlConnection("Server=;UID=;PWD=");
Conn.Open();
SqlDataAdapter Sda = new SqlDataAdapter("Select top 1 [ID],[UserName],[Lable] From User",Conn);
DataSet DsT = new DataSet();
Sda.Fill(DsT);
Response.Write(Thread.CurrentThread.Name);
Conn.Close();
//DsT.Tables[0].Clone();
DataTable Dt = DsT.Tables[0];
for(int i=0;i<Dt.Rows.Count;i++)
{
DataRow Dr = Dt.Rows[i];
Response.Write(Dr[0] + " " + Dr[1] + " " + Dr[2]);
}
Sda.Dispose();
}