如何以编程方式防止或限制资源争用?

What can I do to programmatically prevent or limit Resource contentions?

我创建了一个应用程序,在提供足够数据的情况下无法完成,"The transaction log for database 'tempdb' is full due to 'ACTIVE_TRANSACTION'." 和 "Cannot find table 0."

报告使用的存储过程没有明确引用 "tempdb" 因此它必须是 SQL 服务器自行管理的内容。

无论如何,我 运行 在 Visual Studio 2013 年通过分析 > 性能和诊断进行了 "Resource Contention" 分析。

完成后,它在 "Concurrency Profiling Report" 中告诉我共有 30,790 个争用,其中 "Handle2" 和 "Multiple Handles 1" 占 "Most Contended Resources" 的 99% 以上和“_CorExeMain”,线程 ID 4936 作为 "Most Contended Thread"

我想这已经足够有趣了,但既然我知道了这一点,我能做些什么呢?

30,790 是否过多?听起来像,但我不知道。但再次假设是,这些信息似乎并没有真正告诉我任何有价值的东西,即:我可以做些什么来改善这种情况?如何以编程方式防止或限制资源 and/or 线程争用?

生成的报告没有错误,六封邮件属于 "for information only" 种类。有一个警告:

警告 1 DA0022:#第 1 代集合/#第 2 代集合 = 2.52;第 2 代垃圾回收的发生率相对较高。如果按照设计,程序的大部分数据结构都已分配并长期保留,这通常不是问题。但是,如果此行为是无意的,则您的应用可能正在固定对象。如果您不确定,可以收集 .NET 内存分配数据和对象生命周期信息以了解您的应用程序使用的内存分配模式。

...但是 "a long time" 的数据结构的持久化确实是设计使然。

更新

然后我 运行“.NET 内存分配”报告,在这里我也不确定该怎么做:

1.24亿字节是否过多?分配内存最多的函数,或者分配内存最多的函数有什么不好的地方吗?

我也不明白为什么生成报告后红色竖线会四处移动;它首先在“616”左右,然后移至 0(如上面的屏幕截图所示),现在在 120 左右。

更新 2

我现在看到(在 运行 最终性能检查(仪器)之后)垂直红线只是一只旅鼠 - 无论您将它拖动到哪里,它都会跟随光标。我猜这是有一定目的的...

这就是最终起作用的方法:双管齐下的攻击:

0) 数据库大师重构了存储过程以提高效率。

1) 我重新编写了数据读取代码,将其分成两部分。我确定了要检索的前半部分数据,并得到了它,然后在短暂的停顿后进行第二次传递,检索其余数据。总之,以前是这样的:

. . .
ReadData(_unit, _monthBegin, _monthEnd, _beginYearStr, _endYearStr);
. . .

...现在是这样的:

. . .
if // big honkin' amount of data
{
    string monthBegin1 = _monthBegin;
    string monthEnd1 = GetEndMonthOfFirstHalf(_monthBegin, _monthEnd, _beginYearStr, _endYearStr);
    string monthBegin2 = GetBeginMonthOfSecondHalf(_monthBegin, _monthEnd, _beginYearStr, _endYearStr);
    string monthEnd2 = _monthEnd;

    string yearBegin1 = _beginYearStr;
    string yearEnd1 = GetEndYearOfFirstHalf(_monthBegin, _monthEnd, _beginYearStr, _endYearStr);
    string yearBegin2 = GetBeginYearOfSecondHalf(_monthBegin, _monthEnd, _beginYearStr, _endYearStr);
    string yearEnd2 = _endYearStr;

    ReadData(_unit, monthBegin1, monthEnd1, yearBegin1, yearEnd1);
    Thread.Sleep(10000);
    ReadData(_unit, monthBegin2, monthEnd2, yearBegin2, yearEnd2);
}
else // a "normal" Unit (not an overly large amount of data to be processed)
{
    ReadData(_unit, _monthBegin, _monthEnd, _beginYearStr, _endYearStr);
}
. . .

它现在成功运行到完成,没有任何异常。我不知道问题是否完全与数据库相关,或者是否所有 Excel Interop activity 也有问题,但我现在可以通过此操作生成 1,341KB 的 Excel 文件。