我有以下C#项目,目标是.NET 4.0,它接受源代码文件,动态地将其编译成一个程序集,然后执行该程序集中包含的类型的静态方法.
这可以按预期工作,只要我没有附加调试器启动程序.在那种情况下,我在调用时得到一个例外xmlSerializer.Serialize(sw, family);,更确切地说是System.NullReferenceException一个System.TypeInitializationException内部a System.InvalidOperationException.
如果我采用相同的程序,在项目中包含源代码文件并将其直接编译到主程序集中,无论是否附加调试器,我都不会得到异常.
请注意,我的项目引用了与动态编译时列出的完全相同的程序集.
无论调试器是否附加,为什么动态编译的代码都很重要?我错过了什么?
主文件Program.cs:
using System;
using System.CodeDom.Compiler;
using System.IO;
using System.Reflection;
using System.Linq;
namespace DebugSerializeCompiler
{
class Program
{
static void Main()
{
if (!Environment.GetCommandLineArgs().Contains("Compile"))
{
DebugSerializeCompiler.SerializerTest.Run();
}
else
{
Assembly assembly;
if (TryCompile("..\\..\\SerializerTest.cs", new[]{ "Microsoft.CSharp.dll",
"System.dll", "System.Core.dll", "System.Data.dll", "System.Xml.dll" },
out assembly))
{
Type type = assembly.GetType("DebugSerializeCompiler.SerializerTest");
MethodInfo methodInfo = type.GetMethod("Run");
methodInfo.Invoke(null, null);
}
}
Console.ReadKey();
}
static bool TryCompile(string fileName, string[] referencedAssemblies,
out …Run Code Online (Sandbox Code Playgroud) 在这个关于Disruptor(一个并发框架)的视频中,提到了Java的Atomic*类(例如AtomicLong)的lazySet方法.根据文档,此方法"最终设置为给定值".
有没有人知道实现这个的底层机制是什么(特别是在Windows上的x86,如果这是相关的).它不能是InterlockedExchange(),因为这会设置值并确保在返回之前刷新缓存行,如果我没有弄错的话.
说我有这样的功能
procedure TMyObject.DoSomething(text: string);
begin
// do something important with the text
end;
Run Code Online (Sandbox Code Playgroud)
当我这样称呼方法时
DoSomething('some text', );
Run Code Online (Sandbox Code Playgroud)
代码编辑器在最后一个参数后面的逗号处显示一个红色波浪形,就像我预期的那样.但是,编译器接受此代码,并且所有操作都像逗号不在那里一样.
为什么这似乎是合法的语法?是否有一些历史原因今天仍然支持(我在Delphi 2006中试过这个,其他人似乎也在2007年经历过这个)?
在分析期间,我遇到了一个耗费了相当多时间的函数,但基本上归结为这段非常简单的代码:
function GetSubstring(AInput: PChar; AStart, ASubstringLength: Integer): string;
begin
Result := Copy(AInput, AStart, ASubstringLength);
end;
Run Code Online (Sandbox Code Playgroud)
此函数返回预期的子字符串,但对于较长的输入,它不能很好地扩展.我查看了CPU视图中的汇编程序代码,从我所知道的(我通常不在汇编程序级别工作),似乎AInput在调用之前隐式转换为字符串Copy.
但是,由于此时字符串/字符数组的长度未知,因此转换代码必须遍历它的长度,PChar直到找到空终止符.这可以解释较长输入的可怕缩放.
但是,由于调用者传入的长度PChar,我最初认为可以只转换使用的方法SetString.
function GetSubstring(AInput: PChar; AStart, ASubstringLength: Integer): string;
begin
SetString(Result, AInput + AStart - 1, ASubstringLength);
end;
Run Code Online (Sandbox Code Playgroud)
除了SetString工作从零开始(不是一个基于复制),Copy在验证其输入方面似乎还有许多其他小事情,并非所有这些都被记录(例如,任何小于1的起始值都会发生变化到1).所以上面的天真实现并不总是像原始实现一样.
我的目标是尽可能复制Copy例程,因为这个函数是库的一部分,并且已被我的同事广泛使用.
我想知道以下实现是否实现了这一点,或者我是否需要了解其他任何警告Copy.注意:FLength它的实际长度AInput来自该函数所属模块中的另一部分.我为此示例删除了其他部分.
function GetSubstring(AInput: PChar; AStart, ASubstringLength: Integer): string;
begin
if (AInput = nil) then begin
Result := '';
end else begin
if …Run Code Online (Sandbox Code Playgroud) 我有一个主线程,包含我的WPF GUI和一个或多个后台线程,偶尔需要异步执行主线程中的代码(例如GUI中的状态更新).
有两种方法(我知道,可能更多)来实现这一目标:
TaskScheduler目标线程的同步上下文来调度任务,以及Dispatcher目标线程调用委托.在代码中:
using System.Threading.Tasks;
using System.Threading;
Action mainAction = () => MessageBox.Show(string.Format("Hello from thread {0}", Thread.CurrentThread.ManagedThreadId));
Action backgroundAction;
// Execute in main thread directly (for verifiying the thread ID)
mainAction();
// Execute in main thread via TaskScheduler
var taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
backgroundAction = () => Task.Factory.StartNew(mainAction, CancellationToken.None, TaskCreationOptions.None, taskScheduler);
Task.Factory.StartNew(backgroundAction);
// Execute in main thread via Dispatcher
var dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher;
backgroundAction = () => dispatcher.BeginInvoke(mainAction);
Task.Factory.StartNew(backgroundAction);
Run Code Online (Sandbox Code Playgroud)
我喜欢基于TPL的版本,因为我已经使用了很多TPL,它为我提供了很多灵活性,例如通过等待任务或将其与其他任务联系起来.但是,在迄今为止我看到的WPF代码的大多数示例中,使用了Dispatcher变体.
假设我不需要任何灵活性并且只想在目标线程中执行一些代码,那么一个人比另一个更喜欢一种方式的原因是什么?是否有任何性能影响?
当我在Delphi 2006中创建一个新的VCL应用程序并运行它时(不添加任何我自己的代码或引用我自己的任何单元),应用程序将不会在其任务栏的上下文菜单中拥有所有菜单项.按钮.然而,应用程序的系统菜单(左键单击表单图标时获得的菜单)具有所有常规菜单项.正如您在以下屏幕截图中看到的那样,前者缺少Move(Verschieben),Size(Größe ändern)和Maximize(Maximieren)

我无法在Delphi XE(我可以访问的Delphi的唯一其他版本)中重现这一点,我也没有发现任何其他人报告此行为.
我还查看了属性TForm以及TApplication是否有一个控制这些菜单,但没有找到一个.
我所知道的所有应用程序在这两个菜单中都有相同的菜单项,我也希望我的应用程序也可以.如何让这两个菜单显示相同的项目集?