public IList A()
{ IList aylist = B();
}
public IList B()
{
ArrayList arlist = new ArrayList();
for (int i = 0; i < 100; i++)
{
arlist.Add(i);
} return arlist;
}
A()被其他的调用,因为B()的执行时间比较长,如果执行时间超过10s的时候,我就想在A()中直接返回一个null的值,我考虑用: System.Timers.Timer aTimer = new System.Timers.Timer(10000); //实例化Timer类,设置间隔时间为10000毫秒;
aTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent); //到达时间的时候执行事件
// Only raise the event the first time Interval elapses.
aTimer.AutoReset = false; //设置是执行一次(false)还是一直执行(true);
aTimer.Enabled = true; //是否执行System.Timers.Timer.Elapsed事件;
大家帮忙看看如何高效的写这段代码啊?
{ IList aylist = B();
}
public IList B()
{
ArrayList arlist = new ArrayList();
for (int i = 0; i < 100; i++)
{
arlist.Add(i);
} return arlist;
}
A()被其他的调用,因为B()的执行时间比较长,如果执行时间超过10s的时候,我就想在A()中直接返回一个null的值,我考虑用: System.Timers.Timer aTimer = new System.Timers.Timer(10000); //实例化Timer类,设置间隔时间为10000毫秒;
aTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent); //到达时间的时候执行事件
// Only raise the event the first time Interval elapses.
aTimer.AutoReset = false; //设置是执行一次(false)还是一直执行(true);
aTimer.Enabled = true; //是否执行System.Timers.Timer.Elapsed事件;
大家帮忙看看如何高效的写这段代码啊?
解决方案 »
- 如何写一个正则表达式对IP地址进行验证?
- 求教,关于dataset自增字段
- 求助~大虾们来看看
- 有谁用过XtraGrid里面的GridControl控件,有问题想了好几天也没解决,求教!!
- 在线等,急,循环问题!!
- [急]DataGridView数值列排序问题,在线等,解决马上给分..................
- 无法正常使用字符串,字符串有内容,显示不出来,长度也有.怪?
- 请问一下VS2003和VS2005怎么开启编译警告啊,装好后默认是没有警告的?
- 多个下拉框,共有数据问题
- 如何对datagrid中的编辑行进行数据验证?
- C#在多线程中如何获取控件的值
- 错误:SQL语句结尾之后找到字符,怎么处理?
{
int start = System.Environment.TickCount; //记住起始时间 ArrayList arlist = new ArrayList();
for (int i = 0; i < 100; i++)
{
if (System.Environment.TickCount - start > 10 * 1000) // 如果超时则返回
{
return null;
}
arlist.Add(i);
} return arlist;
}
如果你一定要实现可以这样public IList A()
{ IList aylist = B();
return aylist;
}
public IList B()
{
int timeStamp = Environment.Tickcount;
ArrayList arlist = new ArrayList();
for (int i = 0; i < 100; i++)
{
if(Environment.TickCount - timeStamp > 10000)
{
return null;
}
arlist.Add(i);
} return arlist;
}
你可以做完之后判断呀,具体就是用结速时间-开始的int start = System.Environment.TickCount; //记住起始时间 这里进行你的业务判断
if (System.Environment.TickCount - start > 10 * 1000) // 如果超时则返回
{
return null;
}
}
这里可能就会超过10s啊,如果这样程序不是还在执行吗?这样就会超时 ,我的意思就是这个b()方法如果执行的时间超过10s,就要赶快返回null。
到了if (System.Environment.TickCount - start > 10 * 1000) // 如果超时则返回
{
return null;
}
}可能已经执行时间超时了啊
{
public IList A()
{ IList aylist = B();
return aylist;
} AutoResetEvent[] _events = null;
public IList B()
{
Thread[] _threads = new Thread[10];
_events = new AutoResetEvent[10];
for(int i = 0; i < threads.Length;i ++)
{
_threads[i] = new Thread(RunInTrehad);
_events[i] = new AutoResetEvent(false);
_thread[i].Start(i);
}
AutoResetEvent.WaitAll(_events);
return new List();
} public void RunInThread(object data)
{
int index = Convert.ToInter32(data);
int timeStamp = Environment.Tickcount;
ArrayList arlist = new ArrayList();
for (int i = 0; i < 100; i++)
{
if(Environment.TickCount - timeStamp > 10000) //保证每个线程运行的时间不会超过10s,那么整个运行的时间就不会超过10s
{
_events[i].Set();
return;
}
arlist.Add(i);
} _events[i].Set(); }
}大致意思就是主线程阻塞住等待所有子线程返回,每个子线程的执行时间不会超过10s,超过就立即让线程自动结束,那么整体就不会超过10s了,不要去abort线程,这样会导致资源被耗尽的。
{
System.Timers.Timer aTimer = new System.Timers.Timer(10000); //实例化Timer类,设置间隔时间为10000毫秒;
aTimer.Elapsed+=new ElapsedEventHandler(OnTimedEvent); //到达时间的时候执行事件
// Only raise the event the first time Interval elapses.
aTimer.AutoReset = false; //设置是执行一次(false)还是一直执行(true);
aTimer.Enabled = true; //是否执行System.Timers.Timer.Elapsed事件; B();}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
}
这样B()在继续执行,但是当到了10000毫秒的时候,会调用OnTimedEvent,但是B()还是在执行中,我仅仅提供一个思路。我说过B()业务很复杂,牵涉B()又调用了其他的方法,框架已经好了,我要加上去这个超过时间的限制就返回,不知道如何处理了?谢谢!
我刚刚写的方案应该比较理想的,让线程自己判断时间主动退出去,而且效率也高,因为线程是阻塞住的,不占cpu。
利用thread的join方法,join有3个方法
1,无限期的等待线程zhixing
2,join(int timeout时间)
3,join(timespan)
public class Test
{
public IList A()
{ Thread thread = new thread(new ThreadStrsat(B)) :
thread.start();
therad.join(20000);
}
private B()
{
.......
}
}
然后这样你这样过了20000秒怎么办?还是要去杀线程啊,因为可能前面的线程仍然没有做完啊原则是一定要让其他线程主动退出,
不知道你那些线程是不是不停在做循环,如果是这样倒有个折中的办法,就是循环的开关变量是你这个类的一个私有bool变量,当主线程等待20000秒后,把这个变量变成true,就可以让所有子线程主动退出了。
2,其他的线程是在做循环,一时想不出好的解决方法,如果像你所说的,加上这个bool的变量,那么代码要改的很多了。我是线程中嵌套线程。还有其他的思路吗?
1,其实我用的是webservice的机制。我在webservice调用了一个项目的(libary)的dll。
2,在这个项目的dll,是大的3个线程,然后每个线程又分成5个小的子线程。
3,我在webservice的这端就是写了一个线程去执行这个dll,就是3个大的线程。基本上是这样,因为客户反映有的时候timeout,那么我就想自己控制一个时间20s,如果在20s还是没有查询到结果,那么就主动的返回客户端说目前系统busy(笨招)。您的想法呢?
《应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束 》因为我用户调用我的webservice,那么我开的线程都是基于webservice的。我把所有的线程都置为后台线程,在webservice断开连接的时候,是不是就是所有的线程都中止了呢?
Join就在阻塞等待线程推出,是合理的用法。
Join就在阻塞等待线程推出,是合理的用法。
--------------
我所说的不推荐用,不是说它本身存在问题,而是使用者在使用它时很容易导致相关联的thread互相join导致死锁。
你说的很有道理,是设计上有问题,根据log的记录我已经发现发生资源不够用的问题。目前没有考虑到好的设计框架,是系统在不断的search数据库然后再到内存交互匹配,时间是比较长的。
有如下几点疑问:1,那么说就是我join完毕,其实还是又子线程在运行了?
2,webserverice应用程序域是一个进程(A),那么当一个用户1请求的时候,是在这个进程(A)内,那么其他用户(2-100)请求的时候,是不是共享这个webserverice应用程序域,即这个进程(A)呢?
3,一个进程同时开到20个线程基本上是最优的,这个计算依据是根据什么啊?考虑到CPU以及内存的情况了吗?谢谢!
是的,因为你是超时来实现的,超时了当前线程就不会理会子线程了,子线程当然还在运行2,webserverice应用程序域是一个进程(A),那么当一个用户1请求的时候,是在这个进程(A)内,那么其他用户(2-100)请求的时候,是不是共享这个webserverice应用程序域,即这个进程(A)呢?
当然,java好像是每个请求会去开一个进程,但netframework只会去开线程,所以不会自动关掉。3,一个进程同时开到20个线程基本上是最优的,这个计算依据是根据什么啊?考虑到CPU以及内存的情况了吗?
这个是微软内部的windows专家推荐的,你自己也可以做测试,基本上是每cpu一个进程25个线程,因为本身进程启动后会占掉5-6个线程,所以15-20个线程是最优的。如果你的机器是多cpu的,那么可以开到n cpu * 20个线程的样子。
不知道你的系统到底是怎样的查询,需要同时查多个数据库或者多个表?数据量有多大呢?为什么要采用多线程的方式去查,通常一个查询就够了。提高查询速度,首先考虑的是优化数据库,而不是通过你现在的这种方式,因为你现在的方式是牺牲其他资源来获取查询的并发,很有可能得不偿失。
1,根据合同的类型去分别查询3种类型的合同A,B,C
即:开3和线程去执行数据库查询得到A,B,C类型的合同
2,根据得到的合同类型A,B,C再去开5个小的线程去执行所查询到的合同,根据每份合同的ID,去做相关的匹配,还是会查询数据库,然后再在内存中交互匹配得到search的结果。然后加到IList中。3,A类型的合同比较少,一般是在10S结束,B类型的合同较多,一般14s结束,C类型的合同最多,执行的时间有时会大于20s。所以我就想在不超过20s的时候返回查询结果。粗糙的设计,见笑了,根据我的描述,能否给点建议?占用你的时间,谢谢!
thread B = new Thread(new ThreadStart(BB.ThreadSearch));
thread C = new Thread(new ThreadStart(CC.ThreadSearch));
A.start();
B.start();
C.start();C.Join();
B.Join();
A.Join();因为C阻塞主线程,那么自己感觉这种方式不是很好?不知道是否您有好的建议?
以前看到一个例子:
private static void joinAllThread(object obj)
{
Thread[] threads = obj as Thread[];
foreach (Thread t in threads)
t.Join();
Console.WriteLine("所有的线程结束");
} Thread joinThread = new Thread(joinAllThread);
joinThread.Start(new Thread[] { C, B, A});但是感觉这种方式跟我写的不是一样吗?除非主线程运行的时候有一个线程D,这样就不会阻塞线程D了。?
不知道你最大的数据表有多少数据?有几千万吗?是否对数据库做过优化,怎么一个查询少则要10来秒?这种查询肯定有问题,先从数据库优化开始吧,如果数据量实在太大,可以自己再做索引表,至少先找出这次查询涉及到的所有合同号,然后根据合同号来分配线程,保证每个线程查询的速度尽可能短,能及时释放资源。至于合并合同的操作,为什么不放到调用webservice的一端去操作呢?你调用方是什么?
调用代码:
if ( contracts != null && contracts.Count >0 )
{
int ThreadNumber = Environments.NetThreadNumber;
Thread[] MutiThread = new Thread[ThreadNumber];
NetThreadSearch mutiThread = new NetThreadSearch(
contracts,this,searchParams,airways,
this.searchContext.depAirportGroupList ,
this.searchContext.destAirportGroupList ,
this.searchContext.depZoneList,
this.searchContext.destZoneList);
for (int i = 0; i < ThreadNumber; i++)
{
MutiThread[i] = new Thread(new ThreadStart(mutiThread.MutiThreadSearch));
MutiThread[i].Name = "NET Thread " + i.ToString();
MutiThread[i].Priority = ThreadPriority.Highest;
MutiThread[i].Start();
} for(int i = 0; i < ThreadNumber; i++)
{
MutiThread[i].Join();
} srl = mutiThread.ROUTING;
}处理合同的类:
public void MutiThreadSearch()
{
AbstractSearchStrategy.DbConnection = new SqlConnection(SearchFactory.DBConnection);
AbstractSearchStrategy.DbConnection.Open();
try
{
while( true )
{
if ( contracts.Count == 0 )
{
break;
} Contract contract = null;
mut.WaitOne();
if ( contracts.Count > 0 )
{
contract = (Contract)contracts.GetRange(0,1)[0];
contracts.RemoveAt(0); mut.ReleaseMutex();
}
else
{
mut.ReleaseMutex();
break;
} if(contract.FareType.Trim() != Environments.BULKFARETYPE && contract.FareType.Trim() != Environments.COMMISSIONFARETYPE)
continue; if(airways.Trim().ToUpper() != "ALL" && airways.IndexOf(contract.Airway.AirlineCode.ToUpper()) == -1)
continue; // one NET contract INFO
ArrayList temp = (ArrayList)searchNet.GetAvailableRouting(
contract,
searchParams.Departure,
searchParams.Destination,
searchParams.ReturnFrom,
searchParams.ReturnTo,
searchParams.DepartureDate,
searchParams.ReturnDate,
searchParams.TourType,
null,
this.depAirportGroupList ,
this.destAirportGroupList ,
this.depZoneList,
this.destZoneList
);
mut.WaitOne(); if(temp != null && temp.Count > 0)
{
ROUTING.AddRange(temp);
} mut.ReleaseMutex();
}
}
catch(Exception Ex)
{
log.Error(Ex.Message,Ex);
if (mut.WaitOne())
mut.ReleaseMutex();
} AbstractSearchStrategy.DbConnection.Close();
}
#endregion基本是是这样,在GetAvailableRouting这个方法中就是跟数据库的交互匹配查询的,自己知道在线程中访问数据库是不妥。但是目前考虑不到更好的方法根据代码给点建议!谢谢