我正在开发视频转换Web API。用户将上传他们的视频,api将对其进行转换(使用ffmpeg),然后将其存储。我正在从控制器中调用转换方法。转换方法如下所示:
var arguments = "-i " + inputDir + " -c:v libx264 -preset fast -crf 25 -r 23.976 -ar 44100 -ac 2 -c:a aac -strict -2 -b:a 112k " + outputDir;
var process = new Process()
{
StartInfo = new ProcessStartInfo()
{
UseShellExecute = false,
FileName = ffmpegDir,
CreateNoWindow = true,
Arguments = arguments
},
EnableRaisingEvents = true
};
process.Start();
process.Exited += (sender, args) =>
{
//store the output file
};
当我将其部署到生产环境中时,我遇到了一些严重的问题。如果有一个客户上传他的视频,那就没有问题。但是如果多个客户端尝试同时上传他们的视频,则该应用程序将无响应。我知道视频转换过程需要大量的CPU资源,这就是为什么如果开始多次转换会导致服务器挂断的原因。
我想出了一种解决方案的体系结构,但我不知道如何实现。这是我的主意
最好的方法是什么?我如何跟踪后台是否已在运行任何线程/进程?
答案 0 :(得分:1)
您可以创建一个专用线程来启动新进程。然后添加一个队列以与该线程通信
伪代码:
public class ApiController
{
private Queue<string> queue = new Queue<string>();
private object sync = new object();
public ApiController()
{
// create a thread here or on web app start
}
private void ThreadProc()
{
while (true)
{
string filename = null;
lock (sync)
{
if (queue.Count() > 0)
filename = queue.Dequeue();
}
if (filename != null)
{
// create process
}
else
{
Thread.Sleep(100);
continue;
}
}
}
public void ApiMethod()
{
// save file from request stream and pass name of this file to thread
string filename = ...
lock (sync)
queue.Enqueue(filename);
}
}
这种方法允许您在任何时候只有一个正在运行的进程