【发布时间】:2019-11-08 14:21:22
【问题描述】:
我正在使用 Linq 在循环中创建新线程并启动它们,然后我在以下循环中加入线程。但是,第一个循环引发了一个异常,我什至在加入线程之前就对此感到非常困惑。即使 indexOfHeaders 只有 3 个元素(索引为 0、1、2),我也得到一个索引超出范围异常和 i=3。但更奇怪的是,当我在调试器中中断异常时,即使所有其他局部变量都是可见的,我也看不到 int numberOfThreads 值。这是因为我错误地使用了 linq 或三元运算符吗?当我在调试器中缓慢地单步执行代码时,这些都无法重现。
private static void DecodeFileData(byte[] dataBuffer, UInt64 header, UInt64 trailer)
{
byte[] headerBytesReceive = BitConverter.GetBytes(header);
byte[] trailerBytesReceive = BitConverter.GetBytes(trailer);
IEnumerable<int> indexOfHeaders = StartingIndex(dataBuffer, headerBytesReceive); //int indexOfHeader = Array.IndexOf(HundredKBBuffer, headerBytesReceive);
// spawn up to 10 threads that look at the byte array for the right data
SerialTest.DataFileWriter fileWriter = new SerialTest.DataFileWriter();
int numberOfThreads = indexOfHeaders.Count() < 10 ? indexOfHeaders.Count() : 10;
List<Thread> threadList = new List<Thread>();
for (int i = 0; i < numberOfThreads; i++)
{
Thread decodeThread = new Thread(() => DecodeDataAsync(dataBuffer, headerBytesReceive, trailerBytesReceive, indexOfHeaders.ElementAt(i), fileWriter));
threadList.Add(decodeThread);
decodeThread.Start();
}
for (int i = 0; i < threadList.Count; i++)
threadList.ElementAt(i).Join();
}
public static void DecodeDataAsync(byte[] dataBuffer, byte[] headerBytesReceive, byte[] trailerBytesReceive, int indexOfHeader, SerialTest.DataFileWriter fileWriter)
{ //lots of file writing and stuff that is irrelevent
DecodeFileData 从另一个方法同步调用。 从我发布的代码中可以看出,DecodeDataAsync 是异步的。
【问题讨论】:
-
DecodeDataAsync不会因为你把Async放在最后就变成异步的。 -
我明白了。也许我应该叫它别的名字,我只是为了提醒自己以异步方式调用它。这不是常见的做法吗?
-
请注意,在 LINQ 表达式中使用循环变量将使用我在执行此表达式时所拥有的值。为避免这种情况,请将 i 分配给本地变量并使用它。
-
@Goku - 当
i等于3时,它永远不会运行循环体。这并没有改变那个变量被设置为3这一事实,并且它是正在使用的那个变量的值。
标签: c# multithreading linq .net-core thread-safety