我最近正在使用一个DateTime对象,并写了这样的东西:
DateTime dt = DateTime.Now;
dt.AddDays(1);
return dt; // still today's date! WTF?
AddDays()的智能感知文档说它在日期后添加了一天,但它并没有这样做——它实际上返回了一个添加了一天的日期,所以你必须这样写:
DateTime dt = DateTime.Now;
dt = dt.AddDays(1);
return dt; // tomorrow's date
这个问题以前已经困扰过我很多次了,所以我认为将最糟糕的c#陷阱分类会很有用。
这是一个超级陷阱,我浪费了2天的时间来解决问题。它没有抛出任何异常,只是用一些奇怪的错误消息使web服务器崩溃。我无法在DEV中重现这个问题。此外,项目构建设置的实验以某种方式使它在PROD中消失,然后它又回来了。我终于明白了。
如果你在下面这段代码中发现了问题,请告诉我:
private void DumpError(Exception exception, Stack<String> context)
{
if (context.Any())
{
Trace.WriteLine(context.Pop());
Trace.Indent();
this.DumpError(exception, context);
Trace.Unindent();
}
else
{
Trace.WriteLine(exception.Message);
}
}
所以如果你重视自己的理智:
! !永远不要给Trace方法添加任何逻辑!!
代码应该是这样的:
private void DumpError(Exception exception, Stack<String> context)
{
if (context.Any())
{
var popped = context.Pop();
Trace.WriteLine(popped);
Trace.Indent();
this.DumpError(exception, context);
Trace.Unindent();
}
else
{
Trace.WriteLine(exception.Message);
}
}
也许不是真的抓住你,因为行为写得很清楚在MSDN中,但已经打破了我的脖子,因为我发现它相当反直觉:
Image image = System.Drawing.Image.FromFile("nice.pic");
这家伙留下了“不错”。图片“文件锁定,直到图像被处置。在我面对它的时候,我认为它会很好地加载图标,并没有意识到(一开始),我最终有几十个打开和锁定的文件!Image一直跟踪它从哪里加载文件…
如何解决这个问题?我以为只用一行就行了。我期望FromFile()有一个额外的参数,但没有,所以我写了这个…
using (Stream fs = new FileStream("nice.pic", FileMode.Open, FileAccess.Read))
{
image = System.Drawing.Image.FromStream(fs);
}
Foreach循环变量范围!
var l = new List<Func<string>>();
var strings = new[] { "Lorem" , "ipsum", "dolor", "sit", "amet" };
foreach (var s in strings)
{
l.Add(() => s);
}
foreach (var a in l)
Console.WriteLine(a());
打印五个“amet”,而下面的例子可以正常工作
var l = new List<Func<string>>();
var strings = new[] { "Lorem" , "ipsum", "dolor", "sit", "amet" };
foreach (var s in strings)
{
var t = s;
l.Add(() => t);
}
foreach (var a in l)
Console.WriteLine(a());
LinqToSql批处理速度随着批处理大小的平方而变慢
以下是我探索这个问题的问题(和答案)。
In a nutshell, if you try to build up too many objects in memory before calling DataContext.SubmitChanges(), you start experiencing sluggishness at a geometric rate. I have not confirmed 100% that this is the case, but it appears to me that the call to DataContext.GetChangeSet() causes the data context to perform an equivalence evaluation (.Equals()) on every single combination of 2 items in the change set, probably to make sure it's not double-inserting or causing other concurrency issues. Problem is that if you have very large batches, the number of comparisons increases proportionately with the square of n, i.e. (n^2+n)/2. 1,000 items in memory means over 500,000 comparisons... and that can take a heckuva long time.
为了避免这种情况,您必须确保对于预计有大量项目的任何批处理,您都在事务边界内完成整个工作,在创建每个项目时保存它,而不是在最后进行一次大保存。