Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.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# 如何在不阻塞GUI的情况下等待线程完成?_C#_Multithreading_Data Partitioning - Fatal编程技术网

C# 如何在不阻塞GUI的情况下等待线程完成?

C# 如何在不阻塞GUI的情况下等待线程完成?,c#,multithreading,data-partitioning,C#,Multithreading,Data Partitioning,我有2863个对象的数组。我希望每1000个对象运行两次,通过4个线程读取阵列数据(运行CPU的PC) 目前,我的源代码将数据划分为正确的线程数和运行数: 单次运行大小(默认)=1000个元素 运行次数=2次 额外螺纹管路尺寸=866个元件 开始运行[1/2] 线程作为readdcmtag(i=0,firstIndex=0,lastIndex=249 线程为readdcmtag(i=1,firstIndex=250,lastIndex=499 线程为readdcmtag(i=2,firstIn

我有2863个对象的数组。我希望每1000个对象运行两次,通过4个线程读取阵列数据(运行CPU的PC)

目前,我的源代码将数据划分为正确的线程数和运行数:

单次运行大小(默认)=1000个元素
运行次数=2次
额外螺纹管路尺寸=866个元件

开始运行[1/2]
线程作为readdcmtag(i=0,firstIndex=0,lastIndex=249
线程为readdcmtag(i=1,firstIndex=250,lastIndex=499
线程为readdcmtag(i=2,firstIndex=500,lastIndex=749
线程为readdcmtag(i=3,firstIndex=750,lastIndex=999

开始运行[2/2]
线程为readdcmtag(i=0,firstIndex=1000,lastIndex=1249
线程为readdcmtag(i=1,firstIndex=1250,lastIndex=1499
线程为readdcmtag(i=2,firstIndex=1500,lastIndex=1749
线程为readdcmtag(i=3,firstIndex=1750,lastIndex=1999
作为readdcmtag的额外线程(i=1,firstIndex=2000,lastIndex=2865 然而,当前的源代码一次启动所有线程,而不是等待运行结束。当我从当前运行中加入线程时,GUI挂起。如何解决该问题

源代码是:

nrOfChunks = 2866 / 1000;
int leftOverChunk = 2866  % 1000;

for(int z = 0; z < nrOfChunks; z++)
{
    addToStatusPanel("\nStarting run [" + (z+1).ToString() + " / " + nrOfChunks.ToString() + "]");

    int indexesPerThread = 1000 / 5; #nrOfThreads
    int leftOverIndexes = 1000 % 5; #nrOfThreads

    threads = new Thread[nrOfThreads];
    threadProgress = new int[nrOfThreads];
    threadDCMRead = new int[nrOfThreads];

    for(int i = 0; i < nrOfThreads; i++)
    {
        int firstIndex = (i * indexesPerThread+z*Convert.ToInt32(chunkSizeTextBox.Text));
        int lastIndex = firstIndex + indexesPerThread - 1;

        if(i == (nrOfThreads- 1))
        {
            if(i == (nrOfThreads - 1))
            {
                lastIndex += leftOverIndexes;
            }
        }

        addToStatusPanel("readDCMTags(i=" + i.ToString() + ",firstIndex=" + firstIndex.ToString() + ", lastIndex=" + lastIndex.ToString());

        threads[i] = new Thread(() => readDCMTags(i.ToString(), firstIndex, lastIndex));
        threads[i].Name = i.ToString();

       threads[i].Start();
    }

    if(z == (nrOfChunks - 1))
    {
        int firstIndex = (nrOfChunks * Convert.ToInt32(chunkSizeTextBox.Text));
        int lastIndex = firstIndex + leftOverChunk - 1;

        addToStatusPanel("readDCMTags(i=" + z.ToString() + ",firstIndex=" + firstIndex.ToString() + ", lastIndex=" + lastIndex.ToString());
    }
}
nrOfChunks=2866/1000;
int leftOverChunk=2866%1000;
对于(intz=0;zreaddcmtag(i.ToString(),firstIndex,lastIndex));
线程[i].Name=i.ToString();
线程[i].Start();
}
如果(z==(nrOfChunks-1))
{
int firstIndex=(nrOfChunks*Convert.ToInt32(chunkSizeTextBox.Text));
int lastIndex=firstIndex+leftOverChunk-1;
addToStatusPanel(“readDCMTags(i=“+z.ToString()+”,firstIndex=“+firstIndex.ToString()+”,lastIndex=“+lastIndex.ToString());
}
}

在执行(int z=0;z之后添加线程数组的join命令正在挂起GUI。

将此线程逻辑放在backgroundworker中,然后将backgroundworker的结果发送回界面。这样,当程序处理线程时,界面不会被锁定

您可以找到初始化和使用的msdn示例


我认为这应该是正确的前进方向。

将此线程逻辑放在backgroundworker中,并将backgroundworker的结果发送回接口。这样,当程序处理线程时,接口不会被锁定

您可以找到初始化和使用的msdn示例


我认为这应该是正确的前进方向。

将此线程逻辑放在backgroundworker中,并将backgroundworker的结果发送回接口。这样,当程序处理线程时,接口不会被锁定

您可以找到初始化和使用的msdn示例


我认为这应该是正确的前进方向。

将此线程逻辑放在backgroundworker中,并将backgroundworker的结果发送回接口。这样,当程序处理线程时,接口不会被锁定

您可以找到初始化和使用的msdn示例


我认为这应该是正确的前进方向。

根据定义,如果等待,就会阻塞(当前正在执行的线程阻塞等待其他线程)

相反,您希望在所有线程完成时发生一些事情。“所有线程都已完成”是一个事件。因此,您最好的选择是在后台线程中等待,并在所有线程完成时触发事件

如果GUI对此感兴趣,那么GUI线程将需要订阅该特定事件

编辑:伪代码(未经测试,只是想法)


然后,在allThreadFinishedEvent的处理程序上,您可以做任何您想做的事情(如果您想更改UI中的某些内容,请记住将其分派到主线程,因为这将在bg线程上下文中执行)。

根据定义,如果您等待,则阻塞(当前执行的线程阻塞等待其他内容)

相反,您希望在所有线程完成时发生一些事情。“所有线程都已完成”是一个事件。因此,您最好的选择是在后台线程中等待,并在所有线程完成时触发事件

如果GUI对此感兴趣,那么GUI线程将需要订阅该特定事件

编辑:伪代码(未经测试,只是想法)


然后,在allThreadFinishedEvent的处理程序上,您可以做任何您想做的事情(如果您想更改UI中的某些内容,请记住将其分派到主线程,因为这将在bg线程上下文中执行)。

根据定义,如果您等待,则阻塞(当前执行的线程阻塞等待其他内容)

相反,您想要的是当所有线程都完成时发生一些事情
waitBg = new Thread(() => 
  {
    foreach (thread in threads)
      thread.WaitFor();

     // All threads have finished
     if (allThreadFinishedEvent != null)
        allThreadFinishedEvent();
  }
);