对于processor affinity
上的小项目,我想创建一个更简单的方法,而不仅仅是一堆if(lvProcessors.Items[0].Checked == true && lvProcessors.Items[1] == true etc)
比较它们的确切值,以查看哪些代码需要转移到(IntPtr)
为了使代码更有效率,我想将包含booleans
的数组与至少14个包含booleans
的其他数组进行比较。
示例代码:
var CheckState = new[] { lvProcessors.Items[0].Checked, lvProcessors.Items[1].Checked, lvProcessors.Items[2].Checked, lvProcessors.Items[3].Checked };
//setcore1 == 1, setcore2 == 2, etc
var SetCore1 = new[] { true, false,false,false };
var SetCore2 = new[] { true, true, false, false };
var SetCore3 = new[] { false, true, false, false };
var SetCore4 = new[] { true, false, true, false };
var SetCore5 = new[] { false, true, true, false };
var SetCore6 = new[] { true, true, true, false };
var SetCore7 = new[] { false, false, false, true };
var SetCore8 = new[] { true, false, false, true };
var SetCore9 = new[] { false, true, false, true };
var SetCore10 = new[] { true, true, false, true };
var SetCore11 = new[] { false, false, true, true };
var SetCore12 = new[] { true, false, true, true };
var SetCore13 = new[] { false, true, true, true };
var SetCore14 = new[] { true, true, true, true };
int switchcounter = 1;
switch (switchcounter)
{
case 15:
break;
default:
if (Enumerable.SequenceEqual(CheckState,<insertdynamicarrayname))
{
AffinityState = (IntPtr)switchcounter;
}
else
{
switchcounter++;
goto default;
}
break;
}
因此,如果选中checkbox
中的第一个listview lvProcessors
,var CheckState
将生成包含{ true, false,false,false }
的数组
这又必须与其中一个SetCore
数组进行比较,在这种情况下会导致与SetCore1
匹配。
所以我想知道的是;如何根据代码上的switchcounter
创建动态arrayname,它会融合"SetCore"
和switchcounter.ToString()
,从而创建SetCore1, SetCore2, SetCore3, etc
。
[编辑]
正如@Luaan所建议的那样,我已经将他的代码实现到我希望的样式:
var SetCore1 = new[] { true, false, false, false};
[..]
var SetCore15 = new[] { true, true, true, true };
var allSets = new [] { SetCore1, SetCore2, SetCore3,SetCore4,SetCore5,SetCore6,SetCore7,SetCore8,SetCore9,SetCore10,SetCore11,SetCore12,SetCore13,SetCore14,SetCore15 };
foreach (var set in allSets)
{
MessageBox.Show(counter.ToString());
if (Enumerable.SequenceEqual(set, CheckState))
{
AffinityState = (IntPtr)counter;
break;
}
else if (Enumerable.SequenceEqual(set, CheckState) == false)
{
counter++;
}
}
EditProcess.ProcessorAffinity = (IntPtr)AffinityState;
在此代码中,根据listviewcheckboxes
的输入,它会将相关结果与SetCore
相匹配,并使用counter
它会提供正确的int
在foreach
循环结束时转换并设置非常特定的核心(即1,2或0,2,3等),用于之前选择的所选process
在代码中(不可见)。
感谢关于位掩码的建议,它们看起来很有用,但目前我不知道如何在不将我的应用程序分开的情况下实现它们。
答案 0 :(得分:0)
只需创建一个数组数组:
var allSets = new [][] { SetCore1, SetCore2, SetCore3, ... }
然后你可以使用一个简单的循环:
for (var i = 0; i < allSets.Length; i++)
HandleSet(allSets[i]);
使用Enumerable.SequenceEqual
会有点慢。如果你关心表演(我不认为你必须在这样的情况下做),看看BitArray
- 它的内存要小得多,而且匹配大多是简单的bitmasking。
修改强>
如果您想在bool[]
和int
(或byte
之间转换,无论您需要什么),您可以使用以下内容:
public bool[] ToBoolArray(int val)
{
var bits = new bool[sizeof(int) * 8];
for (var i = 0; i < bits.Length; i++)
{
bits[i] = (val & (1 << i)) > 0;
}
return bits;
}
public int ToInt32(bool[] bits)
{
var output = default(int);
for (var i = 0; i < bits.Length; i++)
{
output |= bits[i] ? 1 << i : 0;
}
return output;
}
这避免了必须处理大量令人讨厌的字符串。使用BitArray
这更简单 - 从BitArray
创建int
是微不足道的(那里是构造函数),并且可以轻松地将其更改回int
如上所述,只需使用bits.Get(i)
代替bits[i]
。
甚至更好,自己上课来处理这个问题:
public sealed class CpuMask
{
private int _bits;
public bool this[int index]
{
get { return (_bits & (1 << index)) > 0; }
set { if (value) _bits |= (1 << index); else _bits &= ~(1 << index); }
}
public CpuMask(int mask)
{
_bits = mask;
}
public CpuMask(IntPtr mask) : this(mask.ToInt32()) { }
public IntPtr ToIntPtr() { return new IntPtr(_bits); }
}