我的一位同事带着一个关于这种方法的问题来找我,导致无限循环.实际的代码有点过于介绍这里,但基本上问题归结为:
private IEnumerable<int> GoNuts(IEnumerable<int> items)
{
items = items.Select(item => items.First(i => i == item));
return items;
}
Run Code Online (Sandbox Code Playgroud)
这应该(你会认为)只是一种非常低效的方式来创建列表的副本.我叫它:
var foo = GoNuts(new[]{1,2,3,4,5,6});
Run Code Online (Sandbox Code Playgroud)
结果是无限循环.奇怪.
我认为修改参数在风格上是一件坏事,所以我稍微改了一下代码:
var foo = items.Select(item => items.First(i => i == item));
return foo;
Run Code Online (Sandbox Code Playgroud)
那很有效.也就是说,该计划已经完成; 没有例外.
更多实验表明这也有效:
items = items.Select(item => items.First(i => i == item)).ToList();
return items;
Run Code Online (Sandbox Code Playgroud)
一样简单
return items.Select(item => .....);
Run Code Online (Sandbox Code Playgroud)
好奇.
很明显,问题与重新分配参数有关,但仅限于评估延迟超出该语句.如果我添加ToList()它的工作原理.
对于出了什么问题,我有一个普遍的,模糊的想法.它看起来像是在Select迭代它自己的输出.这本身有点奇怪,因为IEnumerable如果它迭代的集合发生变化,通常会抛出.
我不明白,因为我并不熟悉这些东西如何工作的内部,这就是重新分配参数导致这个无限循环的原因.
是否有人对内部人员有更多的了解谁会愿意解释为什么无限循环发生在这里?
请注意,我要问的是,使用类似的东西,每隔15毫秒就会调用一次回调函数System.Threading.Timer.我不是在询问如何使用类似System.Diagnostics.Stopwatch甚至是类似的东西准确计算代码QueryPerformanceCounter.
另外,我已经阅读了相关问题:
准确的Windows计时器?System.Timers.Timer()限制为15毫秒
这些都没有为我的问题提供有用的答案.
此外,推荐的MSDN文章" 为Windows实现连续更新,高分辨率时间提供程序"是关于计时而不是提供连续的滴答流.
照这样说...
关于.NET计时器对象有很多不好的信息.例如,System.Timers.Timer被称为"针对服务器应用程序优化的高性能计时器".并且System.Threading.Timer在某种程度上被认为是二等公民.传统的观点认为,System.Threading.Timer是围绕Windows的包装定时器队列定时器,并且System.Timers.Timer完全是另一回事.
现实情况大不相同. System.Timers.Timer只是一个瘦的组件包装器System.Threading.Timer(只需使用Reflector或ILDASM来查看内部System.Timers.Timer,你会看到引用System.Threading.Timer),并有一些代码将提供自动线程同步,所以你不必这样做.
System.Threading.Timer事实证明,它不是 Timer Queue Timers的包装器.至少不在2.0运行时,它是从.NET 2.0到.NET 3.5使用的.使用Shared Source CLI几分钟后,运行时会实现自己的定时器队列,类似于Timer Queue Timers,但实际上从不调用Win32函数.
似乎.NET 4.0运行时还实现了自己的计时器队列.我的测试程序(见下文)在.NET 4.0下提供与.NET 3.5相似的结果.我已经为Timer Queue Timers创建了自己的托管包装器并证明我可以获得1 ms的分辨率(具有相当好的准确性),所以我认为我不太可能错误地读取CLI源代码.
我有两个问题:
首先,是什么原因导致运行时计时器队列的实现如此缓慢?我的分辨率不能超过15毫秒,精度似乎在-1到+30毫秒的范围内.也就是说,如果我要求24毫秒,我会在23到54毫秒之间的任何地方得到滴答声.我想我可以花更多时间使用CLI源来追踪答案,但我想这里有人可能知道.
其次,我意识到这很难回答,为什么不使用定时器队列定时器?我意识到.NET 1.x必须在没有这些API的Win9x上运行,但它们自Windows 2000以来就存在,如果我没记错的话,那就是.NET 2.0的最低要求.是因为CLI必须在非Windows机器上运行吗?
我的计时器测试程序:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace TimerTest
{
class Program
{
const int TickFrequency = 5; …Run Code Online (Sandbox Code Playgroud) 我正在编写一个程序来说明多线程程序中缓存争用的影响.我的第一个切入是创建一个数组,long并显示修改相邻项目如何导致争用.这是程序.
const long maxCount = 500000000;
const int numThreads = 4;
const int Multiplier = 1;
static void DoIt()
{
long[] c = new long[Multiplier * numThreads];
var threads = new Thread[numThreads];
// Create the threads
for (int i = 0; i < numThreads; ++i)
{
threads[i] = new Thread((s) =>
{
int x = (int)s;
while (c[x] > 0)
{
--c[x];
}
});
}
// start threads
var sw = Stopwatch.StartNew();
for (int i = 0; i …Run Code Online (Sandbox Code Playgroud) 我有一个包含Find方法的自定义通用数据结构:
public bool Find(TValue value, IEqualityComparer<TValue> comparer)
{
foreach (var x in items)
{
if (comparer.Equals(value, x))
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我最近从一位客户那里得到了一份报告,他说这会引起他的平等比较,NullReferenceException如果value是,null或者如果该集合中的一个项目是null.
我最初的回答是他的IEqualityComparer<T>.Equals实现是错误的,因为它没有优雅地处理null值.但我还没有找到任何明确支持我的文件.我有一些证据表明我是对的,但没有任何明确的说明.
首先,我已经改变了这个简单的调用,这似乎很愚蠢comparer.Equals:
if (x == null)
{
if (value == null)
return true;
}
else if (value != null && comparer.Equals(value, x))
return true;
Run Code Online (Sandbox Code Playgroud)
其次,Object.Equals的文档说,除其他外:
x.Equals(null)回报false.Equals不能抛出异常.对我来说,这是IEqualityComparer <T> .Equals应该优雅地处理空参数的有力证据.
其他证据是IComparer.Compare的文档说: …
我在几年前编写的应用程序中有一个有界的阻塞队列.我们只是说实现不是很好,但它是有效的.但是,它存在一些性能问题.看起来.NET 4.0 BlockingCollection<T>是正确的替代品,但我需要确保它实际上是一个队列.也就是说,如果以单一生产者,单一消费者的方式使用,它是否可以保证是严格的FIFO?
文档没有具体说明.该BlockingCollection话题不说(在备注):
BlockingCollection<T>类似于传统的阻塞队列数据结构,除了底层数据存储机制被抽象为一个IProducerConsumerCollection<T>.
但没有任何具体说明将按照添加的顺序删除内容.
有人知道吗?
这个System.Threading.ConcurrentQueue.TryDequeue方法在前几天引发了一个例外,让我完全惊讶.这是堆栈跟踪:
System.OverflowException: Negating the minimum value of a twos complement number is invalid.
at System.Math.AbsHelper(Int32 value)
at System.Random..ctor(Int32 Seed)
at System.Threading.Collections.ConcurrentQueue`1.TryDequeueCore(T& result)
at System.Threading.Collections.ConcurrentQueue`1.TryDequeue(T& result)
at MyProgram.ThreadProc() in c:\MyProgram\Main.cs:line 118
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Run Code Online (Sandbox Code Playgroud)
起初我认为问题是TryDequeueCore调用Random具有错误值的构造函数.但进一步调查显示TryDequeueCore调用默认构造函数.它看起来像错误是在Random构造函数中:
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 12 (0xc)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call int32 System.Environment::get_TickCount()
IL_0006: call instance void System.Random::.ctor(int32)
IL_000b: …Run Code Online (Sandbox Code Playgroud) 有没有人知道从一系列图像文件创建视频的可靠方法?在你发布问题之前没有搜索答案之前,在你发出诸如"使用FFMPEG"之类的简单消息之前,请先阅读此消息的其余部分.
我正在尝试创建一个视频,只要它得到广泛支持,从一系列图像(.jpg,.bmp等)开始,无关紧要.我的平台是Windows Server 2008,64位.如果我可以在我的C#程序中制作视频,那很好,但我不反对将一系列图像文件写入目录,然后启动外部程序从这些图像制作视频.
唯一的限制是:它必须在我的Windows Server 2008系统上运行,并且可以编写脚本.也就是说,没有需要操作员干预的GUI程序.
我在StackOverflow上发现了许多类似的问题,并且已经尝试了几种解决方案,所有这些解决方案都有不同程度的挫败感,没有任何成功的解决方案.
FFMPEG看起来像一个伟大的计划.也许是在Linux上.我下载的两个Windows版本已损坏.给定此命令行:
ffmpeg -r 1 -f image2 -i jpeg\*.jpg video.avi
Run Code Online (Sandbox Code Playgroud)
其中一个构建会读取图像,然后由于数据执行阻止而崩溃.另一个读取第一个文件然后吐出一条错误消息"无法找到合适的文件jpeg/image2.jpg编解码器".有帮助,那.无论如何,在Windows下,FFMPEG看起来像一个非首发.
以前发布的一个答案推荐Splicer.它看起来很不错.我编译了示例并尝试运行,但是收到了一些关于未找到文件的神秘错误消息.看起来COM类没有注册.我想我需要安装一些东西(DirectShow,也许,虽然我认为已经安装了?).根据需要,我可能很难在服务器上安装它.("什么?为什么在服务器上需要它?")
另一个答案提出了Code Project 的AviFile库.这看起来很简单:围绕Windows AviFile子系统的包装器.除了包创建的AVI文件似乎具有所有帧,但只有第一帧显示我在Windows Media Player中播放AVI.那么,如果您尝试创建压缩视频,该程序会抛出异常.
所以,我想知道是否有一种好的,可靠的方式来做我想要的:在Windows系统上,通过一系列图像创建AVI或其他常见的视频文件格式,通过.NET API或使用外部计划.有帮助吗?
我最近工作的一个问题让我希望我可以丢掉文件的正面.如果你愿意,有点像"前面的截断".在后端截断文件是一种常见的操作 - 我们做的事情甚至没有考虑太多.但是砍掉文件的正面?起初听起来很荒谬,但这只是因为我们受过训练才认为这是不可能的.但是在某些情况下,垂直操作可能很有用.
一个简单的例子(当然不是唯一或必然是最好的例子)是FIFO队列.您正在将新项目添加到文件末尾,并从前面将项目从文件中提取出来.文件随着时间的推移而增长,前面有一个巨大的空白空间.对于当前的文件系统,有几种解决此问题的方法:
但是如果有一个lop操作,从队列中删除一个项目就像更新文件开头标记一样简单.事实上,就像截断文件一样简单.那么,为什么没有这样的操作呢?
我对文件系统实现有一点了解,并且没有看到任何特殊原因这很难.它看起来像所有它需要的是另一个单词(dword,也许?)每个分配条目,以说明文件在块中的开始位置.对于1美元以下100美元以下的驱动器,这样的功能似乎是一个相当小的代价.
如果您可以像在最后截断那样有效地删除文件的前面,那么还可以使其他任务变得更容易?
你能想到这个功能无法添加到现代文件系统的任何技术原因吗?其他非技术原因?
令我烦恼的是,当我将目标从.NET Framework 3.5更改为.NET Framework 4.0时,Visual Studio 2010将App.config文件添加到我的所有.EXE项目中.所以我的自动构建一直在破坏,直到我检查了那些新文件.
有什么特别的原因我不能删除这些App.config文件?或者Visual Studio是否会继续将它们添加到我的项目中?
我将避免咆哮一种将无用文件添加到我的项目中的工具...
澄清:
我明白这app.config是为了什么.我不明白的是,app.config当我将项目更改为目标.NET 4.0而不是.NET 3.5时,Visual Studio 2010会将文件添加到现有项目中.我的应用程序不需要app.config中的任何东西来运行,所以我唯一合理的结论是Visual Studio出于某种原因需要app.config来编译,或者有人认为他们比我更了解我的应用程序必须有app.config,即使我不想要一个.
哎呀......我咆哮了.
进一步澄清:
将项目从Visual Studio 2008转换为Visual Studio 2010不是问题.当我将目标从.NET Framework 3.5更改为.NET Framework 4.0时,app.config将添加到项目中.app.config包含以下内容:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
Run Code Online (Sandbox Code Playgroud)
当我将其更改回目标.NET Framework 3.5时,app.config文件被修改为:
<supportedRuntime version="v2.0.50727"/>
Run Code Online (Sandbox Code Playgroud)
我想我看到他们正在尝试做什么,但自动添加app.config文件是一个非常糟糕的主意.
我正在尝试将我的ASP.NET应用程序配置为接受使用对称密钥签名的JSON Web令牌(JWT).STS无法使用证书,所以我们使用它们的对称密钥支持.
在我的结尾,我正在使用微软的JWT开发者预览版.不幸的是,我没有看到任何关于如何使用对称密钥的示例.在使用各种工具进行一些挖掘后,我发现NamedKeyIssuerTokenResolver并发现我可以将其配置为使用对称密钥.例如:
<securityTokenHandlers>
<add type="Microsoft.IdentityModel.Tokens.JWT.JWTSecurityTokenHandler,Microsoft.IdentityModel.Tokens.JWT" />
<securityTokenHandlerConfiguration>
<certificateValidation certificateValidationMode="PeerTrust" />
<issuerTokenResolver
type="Microsoft.IdentityModel.Tokens.JWT.NamedKeyIssuerTokenResolver,
Microsoft.IdentityModel.Tokens.JWT">
<securityKey
symmetricKey="+zqf97FD/xyzzyplugh42ploverFeeFieFoeFooxqjE="
name="https://localhost/TestRelyingParty" />
</issuerTokenResolver>
</securityTokenHandlerConfiguration>
</securityTokenHandlers>
Run Code Online (Sandbox Code Playgroud)
我不完全确定我应该在name那里使用什么.应该是观众Uri,也许是发行人Uri?无论如何,我知道如果我不包含a name,我的程序启动时会出现异常,因为该securityKey元素需要该属性.
无论如何,这仍然无法解决问题.在我对STS进行身份验证后,我得到以下异常:
[SecurityTokenValidationException: JWT10310: Unable to validate signature. validationParameters.SigningTokenResolver type: 'Microsoft.IdentityModel.Tokens.JWT.NamedKeyIssuerTokenResolver', was unable to resolve key to a token.
The SecurityKeyIdentifier is:
'SecurityKeyIdentifier
(
IsReadOnly = False,
Count = 1,
Clause[0] = Microsoft.IdentityModel.Tokens.JWT.NamedKeyIdentifierClause
)
'. validationParameters.SigningToken was null.]
Microsoft.IdentityModel.Tokens.JWT.JWTSecurityTokenHandler.ValidateSignature(JWTSecurityToken jwt, TokenValidationParameters validationParameters) +2111
Microsoft.IdentityModel.Tokens.JWT.JWTSecurityTokenHandler.ValidateToken(JWTSecurityToken jwt, TokenValidationParameters validationParameters) …Run Code Online (Sandbox Code Playgroud)