我有以下测试代码:
void Button_Click(object sender, RoutedEventArgs e)
{
var source = new CancellationTokenSource();
var tsk1 = new Task(() => Thread1(source.Token), source.Token);
var tsk2 = new Task(() => Thread2(source.Token), source.Token);
tsk1.Start();
tsk2.Start();
source.Cancel();
try
{
Task.WaitAll(new[] {tsk1, tsk2});
}
catch (Exception ex)
{
// here exception is caught
}
}
void Thread1(CancellationToken token)
{
Thread.Sleep(2000);
// If the following line is enabled, the result is the same.
// token.ThrowIfCancellationRequested();
}
void Thread2(CancellationToken token)
{
Thread.Sleep(3000);
}
Run Code Online (Sandbox Code Playgroud)
在线程方法中,我不会抛出任何异常,但是我会TaskCanceledException
进入try-catch
启动任务的外部代码块.为什么会发生token.ThrowIfCancellationRequested(); …
我的程序抛出一个错误,它无法通过catch(Exception e)
块处理然后崩溃:
访问冲突已损坏的状态异常.
这是奇怪的事情,因为,据我所知,从非托管代码抛出了损坏的状态异常,而在这里我在调用StringBuilder方法时得到了这个异常.
代码在后台线程中运行并且不时崩溃,这是不容易再现的.所以我将WinDbg附加到进程并具有以下异常堆栈:
000000001dabd8c8 000007feea129a1d [HelperMethodFrame: 000000001dabd8c8]
000000001dabda00 000007fee90cfce8 System.Text.StringBuilder.ExpandByABlock(Int32)
000000001dabda40 000007fee90cfba4 System.Text.StringBuilder.Append(Char*, Int32)
000000001dabdaa0 000007fee9102955 System.Text.StringBuilder.Append(System.String, Int32, Int32)
000000001dabdaf0 000007ff00bf5ce3 MineUtils.Common.Strings.Strings.Replace(System.String, System.String, System.String, Boolean, Boolean)
000000001dabdb90 000007ff00bf5a59 MineUtils.Common.Strings.Strings.RemoveSubstrings(System.String, System.String, System.String, Boolean) [D:\Programs\Visual Studio 2005 Projects\MineUtils.Common\Strings\Strings.Common-Main.cs @ 1481
Run Code Online (Sandbox Code Playgroud)
WinDbg显示发生此异常:
EXCEPTION_RECORD: ffffffffffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 000007feea129a1d (clr!WKS::gc_heap::find_first_object+0x0000000000000092)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000000
Parameter[1]: 0000000000003d80
Attempt to read from address 0000000000003d80
Run Code Online (Sandbox Code Playgroud)
我读过这样的异常可以使用方法属性[HandleProcessCorruptedStateExceptions]来处理,但是如果我只使用StringBuilder,为什么会发生这种异常呢?
这是之前的WinDbg分析(StringBuilder.ToString()
导致异常):
*******************************************************************************
* * …
Run Code Online (Sandbox Code Playgroud) 我正在研究保护我的代码免受反编译的方法.
这里有几个好的线程描述了混淆和代码打包作为保护代码的可能方法.但是,当使用字符串方法/属性名称时,混淆不适用于反射.许多人不建议使用混淆.
所以我现在决定不再使用上述任何一项.但是,我有部分代码需要加密,例如,带有IP的数据库连接字符串,登录名和密码都存储在代码中const string
,与电子邮件帐户数据一样简单.
在ASP.NET中,有一个选项可以将敏感数据移动到.config
文件并对其进行加密,但这需要服务器密钥,即链接到单个计算机.我没有读太多关于它,但我想类似的东西可用于桌面应用程序.但我需要这个在任何安装了应用程序的计算机上工作.
这里有一个问题:有没有办法对这些数据进行编码/保护,使其无法与反编译代码一起阅读?
我将WinDbg附加到一个正在运行的进程并让进程崩溃(我有一个单独的问题重新说明那个案例).程序崩溃后,WinDbg停止并允许我调试程序.我使用命令".dump/ma"进行了故障转储以进行进一步调查.
该程序编译为"任何CPU",我使用WinDbg x64进行转储.现在我再次在同一台计算机上打开WinDbg x64并打开故障转储.这是它说的:
Loading Dump File [C:\crashdump.dmp]
User Mini Dump File with Full Memory: Only application data is available
Symbol search path is: SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows 7 Version 7601 (Service Pack 1) MP (8 procs) Free x64
Product: WinNt, suite: SingleUserTS
Machine Name:
Debug session time: Mon Aug 15 10:24:57.000 2011 (UTC + 1:00)
System Uptime: 17 days 0:54:39.021
Process Uptime: 12 days 14:01:31.000
................................................................
...............................................................
This dump file has an exception of interest stored in …
Run Code Online (Sandbox Code Playgroud) 甲字符串表示的对象实例属性的可采取用Expression<Func<T>>
:
string propertyName = ((MemberExpression) property.Body).Member.Name;
Run Code Online (Sandbox Code Playgroud)
但是,如果我没有(不想创建)实例呢?在这种情况下如何获取属性名称?
解释
我需要一个对象的属性名称的字符串表示.
假设有一个实体
public class Customer
{
public int ID;
public string Name;
}
Run Code Online (Sandbox Code Playgroud)
现在我想将这个实体的键表达式传递给其他函数,因此我需要字符串"ID",但我不想像字符串那样硬编码SomeOtherFunction("ID")
,而是使用表达式SomeOtherFunction(ExpressionReader.GetString(() => CustomerInstance.ID))
.为此,我需要提供实体实例.
现在我想在不创建实例的情况下做同样的事情.
在SQL Server中,我们可以指定字段类型varchar(n)
:
存储大小是输入数据的实际长度(以字节为单位),而不是n个字节.
通常在规划数据库结构时,我会尝试想象存储在这些varchar
字段中的字符串的最大可能长度,然后设置该想象的大小+ varchar
字段的一些备份.有时可能会发生最初提供的空间不足以进行现场,然后我需要增加长度.
但实际上,是否值得将该varchar
领域限制在一定的价值范围内,而不仅仅是设置类似的东西varchar(5000)
,甚至varchar(max)
是100%适合这种情况的东西?当我限制该n
长度时,SQL Server或索引组织中的页面组织是否有任何优势?
更新
这就是我的意思(优势):https://stackoverflow.com/a/5353196/355264
是的,查询优化器可以猜测页面中有多少行,如果你有很多大于必要的varchar字段,SQL Server可以在内部猜测错误的行数.
以上是真的吗?还有其他优点吗?
我的多线程托管程序中存在堆损坏.做一些测试我发现只有当程序中的后台线程处于活动状态时(它们是可切换的)才会发生损坏.线程使用一些第三方组件.
在检查了线程和第三方组件的代码(使用.NET Reflector)后,我发现它们都是托管的,即没有 "不安全"或"DllImportAttribute"或"P/Invoke".似乎纯托管代码导致堆损坏,这可能吗?
UPDATE
除了使用Marshal类之外,是否有可能在线程未正确同步的情况下破坏堆?一个例子将非常感激.
亚马逊提供了一批描述我们可以通过MWS发送的源的格式的文档,但是,我们还需要知道他们的响应中会发生什么,可以报告什么状态代码或报告错误时XML的结构等等. ...
我在哪里可以获得这些信息?
我有两个相同类型的对象,需要将属性值从一个对象复制到另一个对象.有两种选择:
使用反射,浏览第一个对象的属性并复制值.
序列化第一个对象并反序列化副本.
两者都符合我的要求,问题是我在速度(成本)方面更好地使用哪些?
例
class Person
{
public int ID { get; set; }
public string Firsthand { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public decimal Weight { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
需要的属性值从复制Person p1
到Person p2
.
对于这个简单的样本 - 哪种方法更快?
更新
对于序列化,我使用此处建议的ObjectCopier:深度克隆对象
对于反射,我使用此代码:
foreach (PropertyInfo sourcePropertyInfo in copyFromObject.GetType().GetProperties())
{
PropertyInfo destPropertyInfo = copyToObject.GetType().GetProperty(sourcePropertyInfo.Name);
destPropertyInfo.SetValue(
copyToObject,
sourcePropertyInfo.GetValue(copyFromObject, null),
null);
}
Run Code Online (Sandbox Code Playgroud) 我正在调试GC堆损坏,并且我想尝试在WinDbg + PageHeap + AppVerifier + GCStress下运行程序.
我在文章软件崩溃中找到了:故障模块mscorwks.dll,版本1.1.4322.2379我可以像这样启用GCStress:
reg.exe add "HKLM\SOFTWARE\Microsoft\.NETFramework" /f /v HeapVerify /t REG_DWORD /d 1
reg.exe add "HKLM\SOFTWARE\Microsoft\.NETFramework" /f /v StressLog /t REG_DWORD /d 1
reg.exe add "HKLM\SOFTWARE\Microsoft\.NETFramework" /f /v GCStress /t REG_DWORD /d 3
reg.exe add "HKLM\SOFTWARE\Microsoft\.NETFramework" /f /v FastGcStress /t REG_DWORD /d 2
Run Code Online (Sandbox Code Playgroud)
(我正在尝试这种方法.它会永远启动程序.我从注册表中删除了最后两个条目以使其工作,可能是方法本身出了问题.)
或者gc_heap :: garbage_collect中没有非托管模块的.NET 4 Runtime中的文章访问冲突描述了另一种方法:
(DWORD) StressLog = 1
(DWORD) LogFacility = 0xffffffff
(DWORD) StressLogSize = 65536
Run Code Online (Sandbox Code Playgroud)
哪种方式是正确的还是有另一种正确的方法?
c# ×6
.net ×3
debugging ×3
windbg ×2
.net-4.0 ×1
amazon-mws ×1
c#-5.0 ×1
deep-copy ×1
dump ×1
lambda ×1
properties ×1
protection ×1
security ×1
shallow-copy ×1
sql-server ×1
windows ×1