C# 多个使用者不一致地更新结果数组
我有一个大文件,每一行都可以单独处理,所以我启动了一个读取器和多个解析器 每个解析器都会将结果写回结果持有者数组,以便进一步处理 我发现,如果启动更多解析器,结果持有者数组每次都会给出不同的内容,无论我使用C# 多个使用者不一致地更新结果数组,c#,concurrency,parallel-processing,blockingcollection,C#,Concurrency,Parallel Processing,Blockingcollection,我有一个大文件,每一行都可以单独处理,所以我启动了一个读取器和多个解析器 每个解析器都会将结果写回结果持有者数组,以便进一步处理 我发现,如果启动更多解析器,结果持有者数组每次都会给出不同的内容,无论我使用ConcurrentQueue还是BlockingCollection还是其他什么 我多次重复运行程序并输出结果数组,如果使用多个解析器,每次都会给出不同的结果 string[] result = new string[nRow]; static BlockingCollection<q
ConcurrentQueue
还是BlockingCollection
还是其他什么
我多次重复运行程序并输出结果数组,如果使用多个解析器,每次都会给出不同的结果
string[] result = new string[nRow];
static BlockingCollection<queueItem> myBlk = new BlockingCollection<queueItem>();
static void Main()
{
Reader();
}
static void parserThread()
{
while (myBlk.IsCompleted == false)
{
queueItem one;
if (myBlk.TryTake(out one) == false)
{
System.Threading.Thread.Sleep(tSleep);
}
else
{
oneDataRow(one.seqIndex, one.line);
}
}
}
static void oneDataRow(int rowIndex, string line)
{
result[rowIndex] = // some process with line
}
static void Reader()
{
for (int i = 0; i < 10; i++)
{
Task t = new Task(() => parserThread());
t.Start();
}
StreamReader sr = new StreamReader(path);
string line;
int nRead=0;
while((line = sr.ReadLine()) != null)
{
string innerLine = line;
int innerN = nRead;
myBlk.Add(new queueItem(innerN, innerLine));
nRead++;
}
siteBlk.CompleteAdding();
sw.close();
while (myBlk.IsCompleted == false)
{
System.Threading.Thread.Sleep(tSleep);
}
}
class queueItem
{
public int seqIndex = 0;
public string line = "";
public queueItem(int RowOrder, string content)
{
seqIndex = RowOrder;
line = content;
}
}
string[]result=新字符串[nRow];
静态BlockingCollection myBlk=新BlockingCollection();
静态void Main()
{
读取器();
}
静态void parserThread()
{
while(myBlk.IsCompleted==false)
{
第1项;
if(myBlk.TryTake(out one)=false)
{
系统线程线程睡眠(tSleep);
}
其他的
{
oneDataRow(一个.seqIndex,一个.line);
}
}
}
静态void oneDataRow(int行索引,字符串行)
{
结果[rowIndex]=//某个进程有行
}
静态无效读取器()
{
对于(int i=0;i<10;i++)
{
Task t=新任务(()=>parserThread());
t、 Start();
}
StreamReader sr=新的StreamReader(路径);
弦线;
int nRead=0;
而((line=sr.ReadLine())!=null)
{
字符串innerLine=行;
int innerN=nRead;
添加(新的queueItem(innerN,innerLine));
nRead++;
}
siteBlk.CompleteAdding();
sw.close();
while(myBlk.IsCompleted==false)
{
系统线程线程睡眠(tSleep);
}
}
类队列项
{
公共int seqIndex=0;
公共字符串行=”;
公共队列项(整数行顺序,字符串内容)
{
seqIndex=行顺序;
行=内容;
}
}
您等待流程完成的方式存在问题:
while (myBlk.IsCompleted == false)
{
System.Threading.Thread.Sleep(tSleep);
}
以下是该物业的说明:
获取此BlockingCollection
是否已标记为已完成添加且为空
在您的情况下,BlockingCollection
的完成不应表示整个操作的完成,因为采集的最后一行可能尚未处理
相反,您应该将辅助任务存储到数组(或列表)中,并等待它们完成
Task.WaitAll(tasks);
通常,除了记录调试信息外,您不应该将
IsCompleted
属性用于任何其他用途。使用它来控制执行流在大多数情况下会引入争用条件。谢谢,这不起作用,我以前使用过它,并重新测试过。@BennyAe等待辅助任务无论如何都很重要,以便观察单个辅助任务中可能发生的任何异常。您可以尝试替换结果[rowIndex]=//具有结果[rowIndex]=rowIndex.ToString()的某个进程
代码>,以排除“带行的某些进程”与问题有关的可能性。当您使用string[]result=new string[nRow]初始化数组时代码>,您如何知道nRow
的值?