gpt4 book ai didi

c# - 在动态创建的多线程中维持参数值? (C#)

转载 作者:太空宇宙 更新时间:2023-11-03 11:34:16 25 4
gpt4 key购买 nike

我不能说我完全理解线程的概念,即使我阅读了很多关于它的文章,我有点厚,我想要的是线程安全参数。我正在向使用 ThreadPool.QueueUserWorkItem 启动的线程发送字符串参数,但我在它之后再次使用相同的线程并使用另一个参数。

我希望它能够处理具有不同参数的不同线程,但它不稳定,这可能是因为我在调用第一个线程后立即更改了参数字符串。我的直觉告诉我使用 Lock,但不知道如何使用以及在何处使用。

顺便说一句,这段代码的输出通常是 3 个线程使用最新的参数(这是 200p 的配置)

我用来调用线程的代码是这样的;

    processThread pt = new processThread();
pt.fileName = AppDomain.CurrentDomain.BaseDirectory + "bin\\ffmpeg.exe";
pt.filePath = Path.Combine(Vci.Core.Sandbox.UploaderControlSandboxPath, fileGuid);
pt.vidPathHigh = AppDomain.CurrentDomain.BaseDirectory + "videos\\480p\\" + fileGuid + ".wmv";
pt.vidPathMid = AppDomain.CurrentDomain.BaseDirectory + "videos\\360p\\" + fileGuid + ".wmv";
pt.vidPathLow = AppDomain.CurrentDomain.BaseDirectory + "videos\\200p\\" + fileGuid + ".wmv";
if (height >= 480)
{
newHeight = (int)Math.Floor(480 * aspectRatio);
initArgs = "-i " + pt.filePath + " -vcodec wmv2 -qscale 2 -s " + newHeight + "x480 -acodec wmav2 -ar 44100 -ab 128k -y \"" + pt.vidPathHigh + "\"";
ThreadPool.QueueUserWorkItem(o => pt.callExecute(initArgs));
newHeight = (int)Math.Floor(360 * aspectRatio);
initArgs = "-i " + pt.filePath + " -vcodec wmv2 -qscale 4 -s " + newHeight + "x360 -acodec wmav2 -ar 44100 -ab 128k -y \"" + pt.vidPathMid + "\"";
ThreadPool.QueueUserWorkItem(o => pt.callExecute(initArgs));
newHeight = (int)Math.Floor(200 * aspectRatio);
initArgs = "-i " + pt.filePath + " -vcodec wmv2 -qscale 6 -s " + newHeight + "x200 -acodec wmav2 -ar 44100 -ab 128k -y \"" + pt.vidPathLow + "\"";
}

我的线程类的代码是这样的;

    public class processThread
{
public string filePath { get; set; }
public string fileName { get; set; }
public string vidPathHigh { get; set; }
public string vidPathMid { get; set; }
public string vidPathLow { get; set; }
public void callExecute(Object o)
{
try
{
executeProcess(fileName, o as string);
}
catch (ThreadAbortException abortException)
{
// do something
}
}

private void executeProcess(string fileName, string arguments)
{
Process myProcess = new Process();
myProcess.StartInfo.FileName = fileName;
myProcess.StartInfo.Arguments = arguments;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.CreateNoWindow = false;
myProcess.StartInfo.RedirectStandardOutput = false;
try
{
myProcess.Start();
}
catch (Exception ex)
{
throw;
}
myProcess.WaitForExit();
myProcess.Close();
}
}

在此先感谢任何帮助!

最佳答案

问题是您正在通过使用 lambda 表达式“捕获”initargs

您不应该以这种方式重用 initargs。您的代码将更具可读性和更易于维护,并且您将避免这个问题。

因此,首先,使用 initargs 的两个不同实例:

string initArgsWithScaleTwo = // 
ThreadPool.QueueUserWorkItem(o => pt.callExecute(initArgsWithScaleTwo));
string initArgsWithScaleFour = //
ThreadPool.QueueUserWorkItem(o => pt.callExecute(initArgsWithScaleFour));

其次,当您分配给 initArgs 时,有很多不必要的重复。维护起来可不好玩。这应该让您开始使用更清晰的版本:

private string GetInitArgs(
string filePath,
int scale,
int newHeight,
string vidPathHigh,
int scanLines
) {
return "-i " + filePath + String.Format(" -vcodec wmv2 -qscale {0} -s ", scale) + newHeight + String.Format("x{0} -acodec wmav2 -ar 44100 -ab 128k -y \"" + pt.vidPathHigh + "\"", scanLines);
}

您可以做更多并使用 String.Format 真正清理整个内容。

然后你可以说

string initArgsWithScaleTwoAnd480ScanLines = 
GetInitArgs(
pt.filePath,
2,
(int)Math.Floor(480 * aspectRatio,
pt.vidPathHigh,
480
);

综上所述,如果线程只是启动新进程,我根本不明白为什么要使用线程。直接启动进程,然后等待它们全部完成。

关于c# - 在动态创建的多线程中维持参数值? (C#),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6806918/

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