c# winform中异步执行WebRequest后返回值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# winform中异步执行WebRequest后返回值相关的知识,希望对你有一定的参考价值。
现在有这样一个东东
一个窗体上有一个label控件text初始值为0,在代码中实现webrequest的BeginGetResponse()方法,如何在每完成一次uri请求后页面上的label控件text属性值加一,循环n次,要求在提交过程中不能影响绘制wingform线程
如果异步执行BeginGetResponse()后再用回调的方法返回状态,是不能访问在主线程创建的label控件的
public void ChangeControl()
this.Invoke((MethodInvoker)delegate
label.Text = (Convert.ToInt32(label.Text) + 1).ToString();
);
每完成一次uri请求后调用一下这个方法 参考技术A 委托+this.invoke
这个是安全调用
http://msdn.microsoft.com/zh-cn/ms171728.aspx
http://msdn.microsoft.com/zh-cn/zyzhdc6b.aspx 参考技术B 委托访问主线程控件, 参考技术C 在form1(窗口代码页面)中写一个这样的方法
public
void
ChangeControl()
this.Invoke((MethodInvoker)delegate
label.Text
=
(Convert.ToInt32(label.Text)
+
1).ToString();
);
每完成一次uri请求后调用一下这个方法
从 C# winforms 执行批处理文件忽略超时
【中文标题】从 C# winforms 执行批处理文件忽略超时【英文标题】:Executing batch file from C# winforms ignores timeout 【发布时间】:2020-11-05 06:06:12 【问题描述】:所有, 我正在尝试通过 C# winforms 应用程序执行一系列批处理文件。在这个早期阶段,使用测试批处理文件,除非我设置 UseShellExecute = true,否则我无法让流程执行遵守批处理文件中的超时,这是我试图避免的事情。我的目标是执行脚本文件并将输出重定向到 GUI,如下面的代码所示:
Process process;
public void ExecuteScript(string workingDirectory, string batchFileName)
if (process != null)
process.Dispose();
process = new Process();
process.StartInfo.WorkingDirectory = workingDirectory;
process.StartInfo.FileName = workingDirectory + batchFileName;
process.StartInfo.Arguments = "";
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.EnableRaisingEvents = true;
process.OutputDataReceived += proc_OutputDataReceived;
process.Start();
process.BeginOutputReadLine();
process.Exited += OnProcessExit;
private void OnProcessExit(object sender, EventArgs e)
Console.WriteLine("the script has ended");
private void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
this.Invoke((Action)(() =>
textBox1.AppendText(Environment.NewLine + e.Data);
));
(sender as Process)?.StandardInput.WriteLine();
我的批处理文件如下所示:
@echo off
echo This is a running script
timeout /t 10
echo Done sleeping. Will Exit
exit
我可以调用适当的设置组合来防止命令窗口出现,同时仍然重定向输出并正确执行脚本吗?
【问题讨论】:
【参考方案1】:您的代码的问题是重定向标准输入时不支持timeout
命令。这是一个很好的例子,说明为什么应该总是 重定向 stdout 和 stderr。批处理文件实际上发出了一条错误消息,但是因为您没有捕获 stderr 流,所以您没有看到错误消息。 Stack Overflow 上的太多问题涉及 Process
场景,如果人们查看 stderr 输出,就可以轻松解决“不起作用”的场景。
解决timeout
命令的这个限制的方法是使用waitfor
命令,使用一个已知不存在的信号名称和一个超时值,例如waitfor /t 10 placeholder
.
这是一个完全独立的控制台程序,它演示了重定向标准输入时timeout
命令的失败,以及waitfor
的解决方法:
const string batchFileText =
@"@echo off
echo Starting batch file
timeout /t 5
waitfor /t 5 placeholder
echo Timeout completed
exit";
static void Main(string[] args)
string batchFileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".bat");
try
File.WriteAllText(batchFileName, batchFileText);
ProcessStartInfo psi = new ProcessStartInfo
FileName = batchFileName,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
;
Process process = new Process
EnableRaisingEvents = true,
;
process.OutputDataReceived += Process_OutputDataReceived;
process.ErrorDataReceived += Process_ErrorDataReceived;
process.Exited += Process_Exited;
process.StartInfo = psi;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
finally
File.Delete(batchFileName);
private static void Process_Exited(object sender, EventArgs e)
WriteLine("Process exited");
private static void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
if (e.Data != null)
WriteLine($"stdout: DateTime.Now:HH:mm:ss.sss: e.Data");
private static void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
if (e.Data != null)
WriteLine($"stderr: DateTime.Now:HH:mm:ss.sss: e.Data");
请注意,如果发生超时,waitfor
命令会向 stderr 写入一条消息(在这种情况下总是如此)。您可能希望也可能不希望它出现在捕获的 stderr 流中。如果没有,您可以使用2>nul
专门重定向该命令的标准错误。例如。 waitfor /t 10 placeholder 2>nul
.
【讨论】:
以上是关于c# winform中异步执行WebRequest后返回值的主要内容,如果未能解决你的问题,请参考以下文章
c#中我要实现大量的httpwebrequest,但是不想winform假死住,请问用多线程还是异步?
C# 自己写的Winform程序批量导入Excel文件到Oracle数据库的过程中,程序运行会很慢!而且Winform窗体会卡