小编Jam*_*ing的帖子

如何将源代码嵌入到pdb中,并让调试器使用它?

注意:我的目标关注点是使用常规MSIL定位CLR的C#,以防有些内容适用于此但不是更常见的情况.

一些现有的源代码调试支持示例

最近发布了Sourcepack项目,该项目允许用户重写pdb文件中的源路径以指向不同的位置.当您拥有程序集的源代码时,这非常有用,但不希望尝试将其放入与构建时完全相同的文件系统位置.

http://lowleveldesign.wordpress.com/2011/08/26/sourcepack-released/

对于开源项目,使用http://www.symbolsource.org/作为简化项目用户获取符号和来源的方法是一个很好的主意.

问题

但是,由于法律或方便的原因,使用这种方法的项目通常不太可行.此外,可能正在调试项目的人员组可能相对较小或包含在内.

默认情况下,项目的pdb包含指向磁盘上文件的指针(IIRC),然后源索引可以添加嵌入源位置指针的功能(例如,在版本控制系统中),然后使用源服务器指向实际获取源的指针.

目标

看起来事情可能更简单(对于某些构建,例如调试和/或仅内部),只需将实际源放入pdb(实际上只是取消引用当前在PDB中写入的指针).看起来你可以跳过整个源服务器部分(至少在理论上)并消除对调试时故事的一些依赖.是否将源存储为压缩源在很大程度上是正交的,但是为了使现有调试器的实现更简单,第一遍可能不会这样做.

由于PDB匹配二进制故事已经非常好,因此将源放入PDB甚至比源服务器指针更好,因为指针可能会随着时间的推移而中断(源控制系统移动或更改为不同的系统,或者无论如何,但坐在PDB中的实际来源是"永远".

这与"源服务器"的支持有何不同?

(这是在Tigran评论之后通过编辑添加的,询问有什么好处)

应该与之进行比较的"基线"场景是使用当今"普通"源服务器实例的"正常"调试体验.在那种情况下,(AFAIK)调试引擎从PDB获取指针(通过备用流),然后使用注册的源服务器尝试通过该指针获取源.由于给定的程序集通常包含多个源文件,因此有一个指针包含一个基本位置,或者PDB中有多个指针(或其他内容),但这应与此讨论正交.

对于保持源隐藏/不可访问的项目(大多数Microsoft产品,例如,包括Windows,Office,Visual Studio等),然后让PDB包含指针,FAR优于包括实际源(即使它是加密).没有必要的网络访问和权限,这样的指针毫无意义,所以这种方法意味着您可以将PDB发送给地球上的任何人,而不必担心他们能够访问您的来源(最糟糕的情况是,他们可以看到您的来源如何树的安排,我想).

但是,有两大组项目(特别是构建),其中"隐藏源"的好处不存在.

第一个是仅供有权访问源的人使用的构建.在你自己的机器上完成不会离开那台机器的构建就是一个很好的例子,因为攻击者无论如何都需要从你的文件系统中读取文件以获取源代码,因此从一个文件(.cs)读取另一个文件(. pdb)在攻击难度/向量方面是一个相对较小的差异.类似地,完成并推送到测试/暂存环境的构建,其中访问机器上的pdb的人员等于或者可以正常访问源的人员的子集.

第二个(有点明显)是开源项目,项目的来源无论如何都已经开放给所有人,因此隐藏任何人的来源没有任何好处.

请注意,这可以相对容易地扩展,以包括加密形式的源(因为我们已经在讨论必须存储格式/编码数据),但增加的复杂性将使这种情况可能不太有用而不仅仅是使用'普通'源服务器.

好处?

通过上面的描述,允许这一点的潜在好处列表包括(但不限于:)这些当下突然出现在我的脑海中:

  • 无需处理设置源服务器支持.它只是工作(IJW),至少在调试器知道如何查看pdb时.
    • 与此同时,你仍然可以做一个"固定"的源服务器,它只是一个虚拟的,它提取源并将其反馈给调用者.这样的配置对于每个人来说都是相同的(例如,使用localhost),仍然消除了实际配置源服务器的当前需求
  • 构建不需要包含'源索引'
    • 由于构建读取源文件并且无论如何都要写入pdb文件,我们只是修改pdb中写入的内容,而不是为了进行网络调用或读取内存中没有的数据而进行任何构建时间性操作.
    • 在'native'构建支持源代码之前,它可能是一个简单的构建后步骤,可能首先通过Sourcepack项目的一个小分支实现,因为它已经完成了读取/修改PDB文件的工作:)
  • 不依赖于具有源控制系统的团队/项目
  • 不依赖于检查到源控制系统的每个文件的特定版本(大多数人不会检查他们在IDE中执行的每个构建)
  • 无需访问具有该文件的特定源控制系统
    • 例如,在DVCS情况下,PDB指针可能是git或mercurial或其他任何"随机"实例,不一定是你有权访问的
    • 源服务器工具跟踪该版本回到您有权访问的源控制服务器实例(如果它甚至存在)尚不存在AFAIK)
  • 如果项目死亡(被删除)或移动,没问题
    • 例如,如果项目从一个移动到另一个:自托管,sourceforge,github,bitbucket,codeplex,code.google.com等.
  • 如果您正在调试的计算机没有(或不充分)网络访问,则没问题
    • 例如,如果您正在将"网络KVM"放入一个用于调试问题的框中,但它没有网络,或者它只能与断开连接的网络通信,以致无法访问您的源控制服务器.
  • 在极端情况下,能够从构建中恢复一些项目源.;)

注意:另一种方法是在实际程序集中包含源代码(例如,作为资源),但pdb是一个更好的选择(很容易发布没有pdb的构建,如果源代码在pdb中,则没有正常的运行时性命中因为程序集是相同的代码和相同的大小等)

如何实施?

从表面上看,这种支持看起来似乎不太难添加,但我觉得这是因为我对所涉及的机制并不是很了解,而不是实际上是一件简单的事情.实施.:)

我的猜测将是:

  1. 添加一个类似于Sourcepack的构建后步骤,但不是更改指针,而是用实际源代替它.
    • 根据源服务器需要执行的操作,可能需要获取前缀,或者实际源将位于不同的备用数据流中,并且"指针"会更新为'source-in-pdb:ads-foo.cs ' 管他呢.前缀或指针可以包括源文件的存储方式(未压缩,gzip,bzip2等,以及文件的编码)
  2. 实现一个"源服务器",它实际上从有问题的pdb中提取源并将其返回.
    • 不知道源服务器'API'是否有足够的信息来获取PDB的位置,更不用说它是否有权实际读取内容.

完整性检查?

随着上面的喋喋不休,问题实际上是:

  • 这种事情已经存在吗?(如果有,请提供指示!)
  • 假设它还不存在,上述内容是否有意义作为首次实现?以上是否存在陷阱或复杂性?
  • 假设上述情况为"否"和"是",是否有一个现有的项目在接受它(它已接近或在其现有范围内)方面有意义?

c# debugging source-server pdb-files

15
推荐指数
1
解决办法
2588
查看次数

如何使用async/await方法管理类似NDC的log4net堆栈?(每个任务堆栈?)

在普通/同步/单线程控制台应用程序中,NDC.Push可以很好地管理"当前项目"(可能在多个嵌套级别,但对于此示例仅为1级).

例如:

private static ILog s_logger = LogManager.GetLogger("Program");

static void Main(string[] args)
{
    BasicConfigurator.Configure();

    DoSomeWork("chunk 1");
    DoSomeWork("chunk 2");
    DoSomeWork("chunk 3");
}

static void DoSomeWork(string chunkName)
{
    using (NDC.Push(chunkName))
    {
        s_logger.Info("Starting to do work");
        Thread.Sleep(5000);
        s_logger.Info("Finishing work");
    }
}
Run Code Online (Sandbox Code Playgroud)

这将导致期望日志输出,显示"程序"右侧的"块X"NDC条目(基本配置器的默认模式)

232 [9] INFO程序块1 - 开始工作

5279 [9] INFO计划块1 - 完成工作

5279 [9] INFO程序块2 - 开始工作

10292 [9] INFO计划块2 - 完成工作

10292 [9] INFO程序块3 - 开始工作

15299 [9] INFO计划块3 - 完成工作

但是,我无法弄清楚如何使用"普通"异步方法来维护它.

例如,尝试这样做:

private static ILog s_logger = LogManager.GetLogger("Program");

static void Main(string[] …
Run Code Online (Sandbox Code Playgroud)

c# logging log4net asynchronous async-await

14
推荐指数
1
解决办法
4619
查看次数

LINQ to Entities/LINQ to SQL:在查询理解过程中从服务器(可查询)切换到客户端(可枚举)?

在许多情况下,我想在服务器端进行一些过滤(有时是投影),然后切换到客户端以进行LINQ提供程序本身不支持的操作.

天真的方法(基本上就是我现在所做的)就是把它分解成多个查询,类似于:

var fromServer = from t in context.Table
                 where t.Col1 = 123
                 where t.Col2 = "blah"
                 select t;

var clientSide = from t in fromServer.AsEnumerable()
                 where t.Col3.Split('/').Last() == "whatever"
                 select t.Col4;
Run Code Online (Sandbox Code Playgroud)

然而,有很多次这是更多的代码/麻烦,而不是真正的价值.我真的很想在中间做一个"切换到客户端".我已经尝试了各种使用查询延续的方法,但是在第一个查询结束时执行'select t into foo'后,foo仍然是一个单独的项目,而不是集合,所以我不能AsEnumerable()它.

我的目标是能够写出更像:

var results = from t in context.Table
              where t.Col1 = 123
              where t.Col2 = "blah"
              // Magic happens here to switch to the client side
              where t.Col3.Split('/').Last() == "whatever"
              select t.Col4;
Run Code Online (Sandbox Code Playgroud)

c# linq linq-to-objects linq-to-entities linq-to-sql

10
推荐指数
2
解决办法
1559
查看次数

如何最好通过流星'尾随-f'mongo中的大型集合?

我在mongo数据库中有一个集合,我附加了一些日志记录类型的信息.我试图找出最有效/最简单的方法来"尾随-f"在流星应用程序中 - 当一个新文档被添加到集合中时,它应该发送给客户端,应该将它追加到最后集合中的当前文档集.

客户端不会被发送也不会保留集合中的所有文档,可能只是最后的~100左右.

现在,从Mongo的角度来看,我没有看到说"集合中的最后N个文档"的方式,因此我们根本不需要应用任何类型.似乎最好的选择是进行自然降序,然后是限制调用,所以类似于$ natural上的mongo doc中列出的内容

db.collection.find().sort( { $natural: -1 } )
Run Code Online (Sandbox Code Playgroud)

因此,在服务器端AFAICT发布这个'最后100个文件'Meteor集合的方式将是这样的:

Meteor.publish('logmessages', function () {
  return LogMessages.find({}, { sort: { $natural: -1 }, limit: 100 });
});
Run Code Online (Sandbox Code Playgroud)

现在,从'tail -f'的角度来看,这似乎具有将'最后100个文档'发送到服务器的正确效果,但是以错误的顺序发送(最新的文档将在Meteor集合的开头)而不是在最后).

在客户端,这似乎意味着需要(不幸的是)反转集合.现在,我没有在Meteor Collection文档中看到reverse()并按$ natural排序:1在客户端上不起作用(这似乎是合理的,因为没有真正的Mongo上下文).在某些情况下,消息将在文档中包含时间戳,并且客户端可以按此排序以获得"自然顺序",但这看起来有点像hacky.

在任何情况下,感觉我可能错过了一个更简单的方法,即从mongo通过流星发布的"最后100个文档插入集合"集合.:)

谢谢!

编辑 - 看起来如果我将Mongo中的集合更改为上限集合,那么服务器可以创建一个可用的光标,以便有效(并且快速)获得添加到集合中的新文档的通知.但是,我不清楚是否/如何通过Meteor集合让服务器这样做.

另一个似乎效率稍低但不需要切换到上限集合(AFAICT)的替代方案是使用智能集合来执行oplog的拖尾,因此至少它是事件驱动而不是轮询,并且因为源中的所有操作收集将是插入,似乎它仍然非常有效.不幸的是,AFAICT我仍然留下了排序问题,因为我没有看到如何将服务器端集合定义为"最后插入的100个文档".:(

如果有一种方法可以在Mongo中创建一个集合作为另一个集合的查询("物化视图"),那么也许我可以在Mongo中创建一个log-last-100"集合视图",然后Meteor将能够只是发布/订阅整个伪集合?

sorting mongodb node.js meteor

10
推荐指数
1
解决办法
1098
查看次数

如何让ELMAH包含会话值?

注意:我知道避免使用会话的各种原因,但这是我继承的项目,所以请跳过任何回复的那部分:)

由于这是一个已解决的问题,我希望有人可以指向ELMAH补丁/分支/分支,其中包括记录会话数据而不是重新发明轮子.

一个奇怪的事情是来自Atif的旧帖子说他们已经记录了:

http://markmail.org/message/ncmdgwm5rmzewbwu

评论者henningst提到在这里添加会话变量:

http://www.hanselman.com/blog/ELMAHErrorLoggingModulesAndHandlersForASPNETAndMVCToo.aspx

另一种方法(我宁愿避免)是将值复制到cookie中

http://www.sharpdeveloper.net/content/archive/2008/11/10/how-to-get-session-or-other-custom-values-into-elmah.aspx

我知道一种替代方法是转换到ELMAH之外的东西(比如Exceptioneer - 请参阅http://exceptioneer.com/Public/ExceptioneerAndELMAH.aspx),但由于这是我目前ELMAH的唯一问题,我宁愿只有一个修补ELMAH而不是切换到别的东西.

elmah session-variables

9
推荐指数
1
解决办法
3269
查看次数

TPL中的错误 - TaskContinuationOptions.ExecuteSynchronously?

我想我在TPL中发现了一个严重的错误.我不确定.我花了很多时间挠挠脑袋,无法理解这种行为.有人可以帮忙吗?

我的情景是:

  1. 我创建了一个简单的任务.没有例外等
  2. 我用ExecuteSynchronously set注册了一个延续.它必须在同一个线程上.
  3. 我在默认的taskcheduler(ThreadPool)上启动任务.起始线程继续并等待它.
  4. 任务开始了.通行证.
  5. 继续从与任务相同的线程开始(使前一个任务完成!)并进入无限循环.
  6. 等待线程没有任何反应.不想再往前走.坚持等待.我在调试器中检查过,任务是RunToCompletion.

这是我的代码.感谢任何帮助!

// note: using new Task() and then Start() to avoid race condition dangerous
// with TaskContinuationOptions.ExecuteSynchronously flag set on continuation.

var task = new Task(() => { /* just return */ });
task.ContinueWith(
   _task => { while (true) { } /* never return */ },
   TaskContinuationOptions.ExecuteSynchronously);

task.Start(TaskScheduler.Default);
task.Wait(); // a thread hangs here forever even when EnterEndlessLoop is already called. 
Run Code Online (Sandbox Code Playgroud)

.net task task-parallel-library

8
推荐指数
1
解决办法
1013
查看次数

Visual Studio 11调试器修复/功能/改进(特别是C#调试)?

很抱歉看起来它可能在某个地方的常见问题/博客中有所涉及,但我的Google-fu显然很弱.:(

VS 2010中的调试体验缺少一些东西似乎在VS 11期间(至少,恕我直言)可能会被修复,但是我很难判断它们是否真的在列表中' 或不.

一些想到的东西:

  • 编辑并继续使用64位控制台应用程序(仅适用于2010年的32位控制台应用程序)
  • 编辑并继续使用Silverlight 5
  • 使用lambdas/anon委托观察(和立即?)表达式
  • 编辑并继续编辑包含lambda的方法

c# debugging edit-and-continue visual-studio

7
推荐指数
1
解决办法
1422
查看次数

配置 EF 在访问导航属性未急切加载(且延迟加载已禁用)时抛出异常

我们有一些应用程序当前正在使用启用了延迟加载的 EF 模型。当我关闭延迟加载(以避免隐式加载和我们的大多数 N+1 选择)时,我宁愿访问应该已经热切加载(或在引用上手动 Load() )抛出异常而不是返回 null(因为特定的异常比 null 引用更好、更容易调试)。

我目前倾向于仅修改 t4 模板来执行此操作(因此,如果 reference.IsLoaded == false,则抛出),但想知道这是否已经是一个已解决的问题,无论是在框中还是通过另一个项目。

任何对可以进行源分析并检测此类问题的插件/扩展/等的引用的奖励积分。:)

entity-framework lazy-loading eager-loading entity-framework-4

6
推荐指数
1
解决办法
670
查看次数

带有任务范围的ninject(或其他IoC)?

我不确定TPL表面是否足够可行,因此,请随意指出替代的替代模式.:)

我试图找出是否可以将Ninject用于ctor注入的依赖项,理想情况下应将其作用域限定为特定的根/父Task实例.

它有点类似于asp.net请求范围,但在这种情况下,它是一个控制台应用程序,它创建N个并行运行的不同任务.我想知道是否有能力让Ninject根据每个根任务实例执行运行时依赖注入,这样作为每个任务的一部分创建的对象图共享给定接口的相同实例,但不同的任务全部有单独的实例.

谢谢!

[编辑]继续搜索,根据"定义对象是其依赖关系的范围"的描述,看起来InNamedScope 可能是正确的答案

c# design-patterns ninject inversion-of-control task-parallel-library

6
推荐指数
1
解决办法
1022
查看次数

如何让SSRS 2008 R2以Excel 2007格式导出/渲染?

我有一个包含~1k列和~17k行的报告,我正在尝试使用SSRS 2008 R2 Nov CTP将其呈现给Excel 2007.

SSRS团队成员已在多个地方提到Excel 2007格式包含在2008 R2中,例如:

http://social.msdn.microsoft.com/Forums/en-US/sqlreportingservices/thread/69545568-73cb-4f4c-8f35-44472ba6d013

现在,它肯定可能还没有进入产品(至少从11月CTP开始),如果是这样的话,那也很好(也就是说它会在产品中出现) ).

repro报告和数据(以及显示现有界面的尝试仍然是Excel 2003格式)附在本博文FWIW的底部:

http://cid-456117cf53a42144.spaces.live.com/default.aspx

sql-server-2008-r2 reporting-services

5
推荐指数
1
解决办法
3万
查看次数

C#中"假"linq理解语法关键字的可用选项?

虽然在某些情况下我会使用方法链编写一些东西(特别是如果它只是一两个方法,比如foo.Where(..).ToArray()),在很多情况下我更喜欢LINQ查询理解语法相反(规范中的"查询表达式"),如下所示:

var query =
    from filePath in Directory.GetFiles(directoryPath)
    let fileName = Path.GetFileName(filePath)
    let baseFileName = fileName.Split(' ', '_').First()
    group filePath by baseFileName into fileGroup
    select new
    {
        BaseFileName = fileGroup.Key,
        Count = fileGroup.Count(),
    };
Run Code Online (Sandbox Code Playgroud)

在一些相当大的块中,我需要将生成的IEnumerable和eager-load加载到数据结构(数组,列表,等等)中.这通常意味着:

  1. 添加另一个局部变量,如var queryResult = query.ToArray(); 要么

  2. 用parens包装查询并在ToArray(或ToList或其他)上标记.

var query = (
    from filePath in Directory.GetFiles(directoryPath)
    let fileName = Path.GetFileName(filePath)
    let baseFileName = fileName.Split(' ', '_').First()
    group filePath by baseFileName into fileGroup
    select new
    {
        BaseFileName = fileGroup.Key,
        Count = fileGroup.Count(),
    }
).ToArray();
Run Code Online (Sandbox Code Playgroud)

我试图找出其他人的选择1)已经使用或2)可以认为添加一些额外的"上下文关键字"是可行的 - 只是将转换为扩展方法的方式与现有方法相同,好像LINQ关键字是'本地'可扩展的:)

我意识到这很可能意味着要么进行某种预处理(不确定C#的这个领域有什么)或者将编译器改为 …

c# linq linq-to-objects nemerle roslyn

3
推荐指数
1
解决办法
625
查看次数

解析c#中包含cData的xml响应文本

我从xml格式的Web服务获得响应,数据在xml节点的cData部分内.现在当我试图提取节点值然后用cdata文本获取值.我怎样才能删除这个并在cdata中获取文本.请建议我这样做的最佳方式.现在写我正在使用正则表达式从结果值中删除cdata.在此先感谢.![CDATA [Xyz]].

<ResumeParserData>
    <ResumeFileName><![CDATA[]]></ResumeFileName>
    <ParsingDate><![CDATA[3/29/2012 1:37:33 AM]]></ParsingDate>
    <TitleName><![CDATA[]]></TitleName>
    <FirstName><![CDATA[abc]]></FirstName>
    <Middlename><![CDATA[Kr]]></Middlename>
    <LastName><![CDATA[abc]]></LastName>
    <Email><![CDATA[xyz@gmail.com]]></Email>
    <Phone><![CDATA[+91 8527502445]]></Phone>
</ResumeParserData>
Run Code Online (Sandbox Code Playgroud)

c# xml xml-parsing

0
推荐指数
1
解决办法
7058
查看次数