gpt4 book ai didi

c# - visual C# 是否有可能比进程运行的进度条有更多的反馈?

转载 作者:太空狗 更新时间:2023-10-30 01:18:56 24 4
gpt4 key购买 nike

我正在使用 Microsoft Visual Studio(Windows 窗体)在 C# 中开发应用程序。我想做的是通过一个 GUI 管理不同的环境。

因此,我的图形用户界面必须异步启动一些进程(这是命令行应用程序)。问题是我只能在进程完成后获得标准输出,这意味着我无法显示进程在运行时正在做什么。因为我要运行的应用程序可能需要相当长的运行时间(上传大文件......)我想在运行时显示过程输出。

因此,我创建了一个 backgroundworker 来将我的 gui 与进程分开,并且我尝试使用一个临时文件来写入进程输出。然后使用 FileSystemWatcher,我可以使用“更改”事件在我的 GUI 中显示消息。

我的问题是,由于临时文件是打开写入的,我无法同时从中读取。这是我的代码,有没有人有办法绕过这个问题?还是其他方式?

 public partial class Form1 : Form
{

Boolean done = false;
private FileSystemWatcher observateur;

public Form1()
{
InitializeComponent();

// delete the temporary file if existing
if (System.IO.File.Exists("C:\\testoutput.txt"))
{
try
{
System.IO.File.Delete("C:\\testoutput.txt");
}
catch (System.IO.IOException exept)
{
Console.WriteLine(exept.Message);
return;
}
}
File.Create("C:\\testoutput.txt");

backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler
(backgroundWorker1_ProgressChanged);
observateur = new FileSystemWatcher();
observateur.Filter = "C:\\testoutput.txt";
observateur.Changed += new FileSystemEventHandler(this.OnChanged);
observateur.Created += new FileSystemEventHandler(this.OnCreate);
}

private void OnChanged(object source, FileSystemEventArgs e)
{
// I tried to bypass the problem of having the file opened by copying it but i doesn't work
File.Copy("C:\\testouput.txt", "C:\\TEMP.txt", true);
}

private void OnCreate(object source, FileSystemEventArgs e)
{
Console.WriteLine("Created");
}

private void button3_Click(object sender, EventArgs e)
{
string outputworker = "";
backgroundWorker1.RunWorkerAsync(outputworker);

while (!done)
{
string text = System.IO.File.ReadAllText("C:\\TEMP.txt");
Thread.Sleep(200);
}
}

void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
outputTextArea.Text = "Processing......" + progressBar1.Value.ToString() + "%";
}



private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string[] args = { "/k " };
string outputWork = e.Argument as string;
backgroundWorker1.ReportProgress(10);

System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.WorkingDirectory = "C:\\XXXXXXXXXX";
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = "cmd.exe";
int nArgs = args.Length;
if (nArgs > 0)
{
process.StartInfo.Arguments = args[0];
}
for (int i = 1; i < nArgs; i++)
{
process.StartInfo.Arguments = String.Concat(process.StartInfo.Arguments, " && ", args[i]);
}
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;

backgroundWorker1.ReportProgress(20);
process.Start();


backgroundWorker1.ReportProgress(40);
System.IO.StreamWriter sIn = process.StandardInput;

sIn.WriteLine("ExternalCommandLineApp1.exe >> C:\\testoutput.txt");
backgroundWorker1.ReportProgress(60);
sIn.WriteLine("ExternalCommandLineApp1.exe >> C:\\testoutput.txt");

System.IO.StreamReader sOut = process.StandardOutput;
backgroundWorker1.ReportProgress(90);

sIn.WriteLine("EXIT");

outputWork = sOut.ReadToEnd();

process.Close();
backgroundWorker1.ReportProgress(100);

e.Result = outputWork;
done = true;
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
string output = e.Result as string;
//outputTextArea.Text = output;
}
}

最佳答案

这不是其他答案中提到的最佳方式,但它仍然可以成功运行。

您可以打开文件进行读/写,而不会阻止其他读/写。只需使用 File.Open 而不是辅助方法并提供额外的参数(FileModeFileShare)这是一个完整的例子。请注意,一个线程保持文件打开以进行写入,第二个线程每次打开和关闭文件并读取所有行:

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string fileName = "c:\\_data\\temp.txt";

Task writer = new Task(() => {

using (FileStream fs = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
using (StreamWriter sw = new StreamWriter(fs))
{
for (int i = 0; i < 50; i++ )
{
sw.WriteLine(DateTime.Now.Millisecond.ToString());
sw.Flush();
Thread.Sleep(500);
}
}


});

Task reader = new Task(() => {
for (int i = 0; i < 50; i++)
{
Thread.Sleep(500);
Console.WriteLine("Read again");
if (File.Exists(fileName))
{
using (FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
using (StreamReader r = new StreamReader(fs))
{
while (!r.EndOfStream)
{
Console.WriteLine(r.ReadLine());
}
}
}
}
});

writer.Start();
reader.Start();

writer.Wait();
reader.Wait();
}
}
}

关于c# - visual C# 是否有可能比进程运行的进度条有更多的反馈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25121554/

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