我的C#应用程序停止响应了很长时间,因为我在一个函数上打破了它停止的调试。
foreach (var item in list)
{
xmldiff.Compare(item, secondary, output);
...
}
我猜这个功能的运行时间很长或者挂起。无论如何,我想等待一段时间(例如5秒)执行此功能,如果超过这个时间,我跳过它并转到循环中的下一个项目。我该怎么做?我发现了一些类似的问题,但它们主要用于进程或异步方法。
答案 0 :(得分:2)
你可以用残酷的方式做到这一点:启动一个线程来完成工作,用超时加入它,然后中止它,如果连接不起作用。
示例:
var worker = new Thread( () => { xmlDiff.Compare(item, secondary, output); } );
worker.Start();
if (!worker.Join( TimeSpan.FromSeconds( 1 ) ))
worker.Abort();
但要注意 - 中止线程并不好看,可能会让你的应用程序不稳定。如果可能,请尝试修改Compare
以接受CancellationToken
取消比较。
答案 1 :(得分:0)
我会避免直接使用线程并使用Microsoft的Reactive Extensions(NuGet“Rx-Main”)来抽象出线程的管理。
我不知道xmldiff.Compare(item, secondary, output)
的确切签名但如果我假设它产生一个整数,那么我可以用Rx做到这一点:
var query =
from item in list.ToObservable()
from result in
Observable
.Start(() => xmldiff.Compare(item, secondary, output))
.Timeout(TimeSpan.FromSeconds(5.0), Observable.Return(-1))
select new { item, result };
var subscription =
query
.Subscribe(x =>
{
/* do something with `x.item` and/or `x.result` */
});
这会自动遍历每个item
并开始xmldiff.Compare
的后台计算,但只允许每次计算在返回默认值{{1}之前花费5.0
秒。 }}
-1
变量是subscription
,因此如果您想在完成之前中止整个IDisposable
,只需致电query
。
答案 2 :(得分:0)
我跳过它并转到循环中的下一个项目
跳过"跳过它",你的意思是"把它留在那里"或者"取消它"?这两种情况完全不同。但对于这两个我建议您使用Task
。
//generate 10 example tasks
var tasks = Enumerable
.Range(0, 10)
.Select(n => new Task(() => DoSomething(n)))
.ToList();
var maxExecutionTime = TimeSpan.FromSeconds(5);
foreach (var task in tasks)
{
if (task.Wait(maxExecutionTime))
{
//the task is finished in time
}
else
{
// the task is over time
// just leave it there
// the loop continues
// if you want to cancel it, see
// http://stackoverflow.com/questions/4783865/how-do-i-abort-cancel-tpl-tasks
}
}
要改进的一件事是"你真的需要逐个完成你的任务吗?"如果它们是独立的,您可以并行运行它们。