gpt4 book ai didi

C# 多个 BackgroundWorker

转载 作者:太空狗 更新时间:2023-10-29 17:49:44 27 4
gpt4 key购买 nike

我正在尝试设置多个 BackgroundWorker 来完成工作,并在不忙时开始执行下一项工作。我似乎无法让它们正常工作。我有以下代码。

当我将 FilesToProcess 设置为等于或小于 MaxThreads 时,它可以完美运行,但如果我将其设置得更高,应用程序就会卡住。

我确信这很简单,但我就是看不到。

using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;

namespace bgwtest
{
public partial class Form1 : Form
{
private const int MaxThreads = 20;
private const int FilesToProcess = 21;
private BackgroundWorker[] threadArray = new BackgroundWorker[MaxThreads];

public Form1()
{
InitializeComponent();
}

private void Form1Load(object sender, EventArgs e)
{
InitializeBackgoundWorkers();
}

private void InitializeBackgoundWorkers()
{
for (var f = 0; f < MaxThreads; f++)
{
threadArray[f] = new BackgroundWorker();
threadArray[f].DoWork += new DoWorkEventHandler(BackgroundWorkerFilesDoWork);
threadArray[f].RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorkerFilesRunWorkerCompleted);
threadArray[f].WorkerReportsProgress = true;
threadArray[f].WorkerSupportsCancellation = true;
}
}

private void button1_Click(object sender, EventArgs e)
{
for (var f = 0; f < FilesToProcess; f++)
{
var fileProcessed = false;
while (!fileProcessed)
{
for (var threadNum = 0; threadNum < MaxThreads; threadNum++)
{
if (!threadArray[threadNum].IsBusy)
{
Console.WriteLine("Starting Thread: {0}", threadNum);

threadArray[threadNum].RunWorkerAsync(f);
fileProcessed = true;
break;
}
}
if (!fileProcessed)
{
Thread.Sleep(50);
}
}
}
}

private void BackgroundWorkerFilesDoWork(object sender, DoWorkEventArgs e)
{
ProcessFile((int)e.Argument);

e.Result = (int)e.Argument;
}

private static void ProcessFile(int file)
{
Console.WriteLine("Processing File: {0}", file);
}

private void BackgroundWorkerFilesRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}

Console.WriteLine("Processed File: {0}", (int)e.Result);
}
}
}

最佳答案

问题似乎是您的工作人员从未完成。为什么会这样,我不确定;这与您运行它们的方法(和线程)本身并未完成这一事实有关。我能够通过创建另一个工作人员将文件分配给工作人员数组来解决问题:

    private BackgroundWorker assignmentWorker;

private void InitializeBackgoundWorkers() {
assignmentWorker = new BackgroundWorker();
assignmentWorker.DoWork += AssignmentWorkerOnDoWork;
// ...
}

private void AssignmentWorkerOnDoWork( object sender, DoWorkEventArgs doWorkEventArgs ) {
for( var f = 0; f < FilesToProcess; f++ ) {
var fileProcessed = false;
while( !fileProcessed ) {
for( var threadNum = 0; threadNum < MaxThreads; threadNum++ ) {
if( !threadArray[threadNum].IsBusy ) {
Console.WriteLine( "Starting Thread: {0}", threadNum );

threadArray[threadNum].RunWorkerAsync( f );
fileProcessed = true;
break;
}
}
if( !fileProcessed ) {
Thread.Sleep( 50 );
break;
}
}
}
}

private void button1_Click( object sender, EventArgs e ) {
assignmentWorker.RunWorkerAsync();
}

我对这个答案不满意,因为我不知道为什么,确切地说,它没有像您最初设计的那样工作。也许其他人可以回答...?至少这会给你一个工作版本。

编辑:您的原始版本不起作用,因为 BackgroundWorkerFilesRunWorkerCompleted 在与 button1_Click(UI 线程)相同的线程上运行。由于您没有释放 UI 线程,因此该线程永远不会被标记为完成。

关于C# 多个 BackgroundWorker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10694271/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com