Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.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# 多个使用者不一致地更新结果数组_C#_Concurrency_Parallel Processing_Blockingcollection - Fatal编程技术网

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
的值?