Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当dotPeek&;时,无法查找/编辑带有反射的字段;堆栈溢出问题反编译器清楚地显示了它_C#_Multithreading_Reflection - Fatal编程技术网

C# 当dotPeek&;时,无法查找/编辑带有反射的字段;堆栈溢出问题反编译器清楚地显示了它

C# 当dotPeek&;时,无法查找/编辑带有反射的字段;堆栈溢出问题反编译器清楚地显示了它,c#,multithreading,reflection,C#,Multithreading,Reflection,我一直在为我的一个项目研究线程,并且我已经开始使用线程名称来记录日志。我的应用程序的主线程被重命名为空字符串(不是由我),所以我需要手动更改它。问题是,线程的Name属性只写了一次,因为它已经设置好了,我无法正常更改它。我环顾四周,找到了一个似乎很有希望的问题。但是,每当我运行它时,都会出现空引用异常。我进一步检查,发现GetField()方法返回null。我通过Jetbrains dotPeek进行了检查,可以清楚地看到m_Name字段及其属性: private Context m_Conte

我一直在为我的一个项目研究线程,并且我已经开始使用线程名称来记录日志。我的应用程序的主线程被重命名为空字符串(不是由我),所以我需要手动更改它。问题是,
线程
Name
属性只写了一次,因为它已经设置好了,我无法正常更改它。我环顾四周,找到了一个似乎很有希望的问题。但是,每当我运行它时,都会出现空引用异常。我进一步检查,发现
GetField()
方法返回null。我通过Jetbrains dotPeek进行了检查,可以清楚地看到
m_Name
字段及其属性:

private Context m_Context;
private ExecutionContext m_ExecutionContext;
private string m_Name; //<- This
private Delegate m_Delegate;
private CultureInfo m_CurrentCulture;
我一运行它,它就返回null。我尝试使用
typeof(Thread)
,但没有效果

最后,我决定对其进行暴力攻击,并决定尝试使用每个绑定标志组合:

Stopwatch stopwatch = Stopwatch.StartNew();
HashSet<FieldInfo> fieldInfos = new HashSet<FieldInfo>();
//Loop over every single bit combination
for (int i = 0; i < 0x01111111; i++)
{
    BindingFlags f = (BindingFlags) i;
    FieldInfo[] infos = thread.GetType().GetFields(f);
    foreach (FieldInfo info in infos) fieldInfos.Add(info);
}
Debug.Log($"Time to search: {stopwatch.Elapsed.TotalMilliseconds:n0}ms");
stopwatch.Restart();
Debug.Log(fieldInfos.Count);
foreach (FieldInfo info in fieldInfos)
{
    Debug.Log(info.Name);
    Thread.Sleep(10);
}
Debug.Log($"Time to log: {stopwatch.Elapsed.TotalMilliseconds:n0}ms");
Stopwatch Stopwatch=Stopwatch.StartNew();
HashSet fieldInfos=新HashSet();
//循环每一位组合
对于(int i=0;i<0x0111111;i++)
{
BindingFlags f=(BindingFlags)i;
FieldInfo[]infos=thread.GetType().GetFields(f);
foreach(信息中的字段信息)fieldInfos.Add(信息);
}
Log($“搜索时间:{stopwatch.appeased.total毫秒:n0}ms”);
stopwatch.Restart();
Debug.Log(fieldInfos.Count);
foreach(FieldInfo中的FieldInfo)
{
Debug.Log(info.Name);
睡眠(10);
}
Debug.Log($“记录时间:{stopwatch.appeased.total毫秒:n0}ms”);

如何使其正确找到字段?

如果要访问线程的非公共成员,请使用
typeof(Thread)

使用系统;
运用系统反思;
使用系统线程;
命名空间堆栈溢出
{
班级计划
{
私有静态void SetName(线程,字符串值)
{
////InvalidOperationException:此属性已设置,无法修改。
//thread.Name=value;
var bindingAttr=BindingFlags.Instance | BindingFlags.NonPublic;
var field=typeof(Thread).GetField(“m_Name”,bindingAttr);
字段设置值(线程、值);
}
静态void Main(字符串[]参数)
{
var thread=thread.CurrentThread;
SetName(线程,“Foo”);
设置名称(线程,“Bar”);
设置名称(线程,“Baz”);
SetName(线程,“你好,StackOverflow!”);
Console.WriteLine(thread.Name);
}
}
}

typeof(System.Threading.Thread).GetField(“m_Name”,System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)
对我来说很好。也就是说,在我看来,你找错了方向。通过反射设置支持字段来绕过属性的一次写入特性显然是一个非常糟糕的主意。你需要想出一个更好的方法来处理你想处理的任何问题。要么尽早执行代码以便设置线程,要么使用其他机制来标识用于日志记录的线程(例如,您可以创建一个字典,将
ManagedThreadId
映射到您选择的任何名称……当然,请记住,线程ID可能会被重用)它在Unity中运行,所以我不能保证我的代码总是在被修改之前被调用。我只打算在编辑器中调试时使用它,因为我注意到在构建中我可以很好地设置它。还有,为什么投票被否决?你认为OP正在访问哪个
System.Threading.Thread
的子类?特别是考虑到这个类是密封的,你当然是对的。我忽略了线程是一个密封类的事实。我会更新我答案的文本,但代码是正确的,按原样工作。“代码是正确的,按原样工作”——OP发布的第一个代码片段也是如此,它与您发布的代码基本相同。那么,你的帖子是如何回答OP的问题的呢?也就是说,你是如何解决他们的问题的?是吗?OP的问题从不显示
线程的定义位置。它可能是一个
HttpWebRequest
。@Always:“它可能是一个HttpWebRequest,用于所有您知道的内容”-true。但如果是这样的话,那么你的帖子就更不相关了。这并不是一个支持你的帖子在任何方面都是一个有用的答案的声明。
Stopwatch stopwatch = Stopwatch.StartNew();
HashSet<FieldInfo> fieldInfos = new HashSet<FieldInfo>();
//Loop over every single bit combination
for (int i = 0; i < 0x01111111; i++)
{
    BindingFlags f = (BindingFlags) i;
    FieldInfo[] infos = thread.GetType().GetFields(f);
    foreach (FieldInfo info in infos) fieldInfos.Add(info);
}
Debug.Log($"Time to search: {stopwatch.Elapsed.TotalMilliseconds:n0}ms");
stopwatch.Restart();
Debug.Log(fieldInfos.Count);
foreach (FieldInfo info in fieldInfos)
{
    Debug.Log(info.Name);
    Thread.Sleep(10);
}
Debug.Log($"Time to log: {stopwatch.Elapsed.TotalMilliseconds:n0}ms");