- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这里的商业智能人员掌握了足够多的 C# 知识,这很危险。
我构建了一个自制的 winforms 应用程序,它本质上是在循环中执行命令行工具来“做事”。所说的东西可能会在几秒钟或几分钟内完成。通常我需要为 DataTable 中的每一行执行一次该工具。
我需要重定向命令行工具的输出并将其显示在“我的”应用程序中。我正在尝试通过文本框这样做。我遇到了有关更新 UI 线程的问题,我自己无法解决这些问题。
为了执行我的命令行工具,我从这里借用了代码:How to parse command line output from c#?
这是我的等价物:
private void btnImport_Click(object sender, EventArgs e)
{
txtOutput.Clear();
ImportWorkbooks(dtable);
}
public void ImportWorkbooks(DataTable dt)
{
ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
cmdStartInfo.FileName = @"C:\Windows\System32\cmd.exe";
cmdStartInfo.RedirectStandardOutput = true;
cmdStartInfo.RedirectStandardError = true;
cmdStartInfo.RedirectStandardInput = true;
cmdStartInfo.UseShellExecute = false;
cmdStartInfo.CreateNoWindow = false;
Process cmdProcess = new Process();
cmdProcess.StartInfo = cmdStartInfo;
cmdProcess.ErrorDataReceived += cmd_Error;
cmdProcess.OutputDataReceived += cmd_DataReceived;
cmdProcess.EnableRaisingEvents = true;
cmdProcess.Start();
cmdProcess.BeginOutputReadLine();
cmdProcess.BeginErrorReadLine();
//Login
cmdProcess.StandardInput.WriteLine(BuildLoginString(txtTabCmd.Text, txtImportUserName.Text, txtImportPassword.Text, txtImportToServer.Text));
foreach (DataRow dr in dt.Rows)
{
cmdProcess.StandardInput.WriteLine(CreateServerProjectsString(dr["Project"].ToString(), txtTabCmd.Text));
//Import Workbook
cmdProcess.StandardInput.WriteLine(BuildPublishString(txtTabCmd.Text, dr["Name"].ToString(), dr["UID"].ToString(),dr["Password"].ToString(), dr["Project"].ToString()));
}
cmdProcess.StandardInput.WriteLine("exit"); //Execute exit.
cmdProcess.EnableRaisingEvents = false;
cmdProcess.WaitForExit();
}
private void cmd_DataReceived(object sender, DataReceivedEventArgs e)
{
//MessageBox.Show("Output from other process");
try
{
// I want to update my textbox here, and then position the cursor
// at the bottom ala:
StringBuilder sb = new StringBuilder(txtOutput.Text);
sb.AppendLine(e.Data.ToString());
txtOutput.Text = sb.ToString();
this.txtOutput.SelectionStart = txtOutput.Text.Length;
this.txtOutput.ScrollToCaret();
}
catch (Exception ex)
{
Console.WriteLine("{0} Exception caught.", ex);
}
}
当我在 cmd_DataReceived () 中实例化我的 StringBuilder 时引用 txtOuput.text 会导致应用挂起:我猜是某种跨线程问题。
如果我在 StringBuilder 中删除对 txtOuput.text 的引用并继续调试,我会在此处遇到跨线程违规:
txtOutput.Text = sb.ToString();
Cross-thread operation not valid: Control 'txtOutput' accessed from a thread other than the thread it was created on.
好吧,不奇怪。我假设 cmd_DataReceived 正在另一个线程上运行,因为我是在 Process.Start() 之后做的事情而击中它的……如果我删除 cmd_DataReceived() 中对 txtOuput.Text 的所有引用并简单地转储命令行文本通过 Console.Write() 输出到控制台,一切正常。
因此,接下来我将尝试使用 http://msdn.microsoft.com/en-us/library/ms171728.aspx 中的信息在 UI 线程上更新我的 TextBox 的标准技术。
我在我的类中添加了一个委托(delegate)和线程:
delegate void SetTextCallback(string text);
// This thread is used to demonstrate both thread-safe and
// unsafe ways to call a Windows Forms control.
private Thread demoThread = null;
我添加了一个程序来更新文本框:
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.txtOutput.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.txtOutput.Text = text;
}
}
我添加了另一个调用线程安全的过程:
private void ThreadProcSafe()
{
// this.SetText(sb3.ToString());
this.SetText("foo");
}
...最后我在 cmd_DataReceived 中这样称呼这个困惑:
private void cmd_DataReceived(object sender, DataReceivedEventArgs e)
{
//MessageBox.Show("Output from other process");
try
{
sb3.AppendLine(e.Data.ToString());
//this.backgroundWorker2.RunWorkerAsync();
this.demoThread = new Thread(new ThreadStart(this.ThreadProcSafe));
this.demoThread.Start();
Console.WriteLine(e.Data.ToString());
}
catch (Exception ex)
{
Console.WriteLine("{0} Exception caught.", ex);
}
}
…当我运行这段文字时,文本框像门钉一样呆在那里,没有得到更新。我的控制台窗口继续更新。如您所见,我尝试通过让文本框显示“foo”与工具的实际输出来稍微简化一些事情——但没有任何乐趣。我的 UI 已死。
那么是什么给了?无法弄清楚我做错了什么。我一点也不喜欢在文本框中显示结果,顺便说一句 - 我只需要能够看到应用程序内部发生了什么,我不想弹出另一个窗口来这样做。
非常感谢。
最佳答案
我认为问题出在这一行:
cmdProcess.WaitForExit();
它在 ImportWorkbooks
方法中,该方法从 btnImport
的 Click 事件方法中调用。因此,您的 UI 线程将被阻塞,直到后台进程完成。
关于c# - 通过 C# 更新 UI 线程(文本框),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8269823/
我正在为一个网站开发应用程序(我无法访问该网站)。 所以我想做以下事情: 那么如何将文本数据从 Android View 传递到网页中的文本框并捕获来自网站的响应? 我试图记住这一切我无法访问任何网站
我有一个文本框,里面有一个很长的 url。我想做的是,当用户点击主页按钮时,我希望光标移动到文本框的开头。 我希望这是正常行为,但事实并非如此,当文本框内的文本很长时,我点击回家,它会转到文本框中当前
我正在做一个WPF登录界面。在我的登录面板中,我有一个登录 TextBox和 PasswordBox .如下图第一张所示,登录文本框中有一个小人类标志,密码框中有一个锁。我将图像设置为文本框背景,然后
是否有任何简单的方法可以使文本在文本框中居中?我正在寻找一些内置函数,但什么也没找到。 最佳答案 将 TextAlignment 属性设置为 Center: 关于wpf - 文本框 - 水平文本居中
是否可以使用 System.Windows.Forms.TextBox(或任何其他方法)输入可随后转换为安全字符串的文本?我希望能够获取输入的值,将其转换为安全字符串并将其写入一个文件,然后可以在需要
是否可以使用 System.Windows.Forms.TextBox(或任何其他方法)输入可随后转换为安全字符串的文本?我希望能够获取输入的值,将其转换为安全字符串并将其写入一个文件,然后可以在需要
我想将纬度和经度的值返回到我的 EditText 中,我已经能够使用 Toast 来做到这一点,但没有通过 实现它>编辑文本。请帮忙 // EditText latEditText =
我是Jquery新手,其实我对JQuery的使用知识是0。我正在尝试使用 JQuery 来实现某些功能。 我有一个带有 iframe 的 html 页面。 iframe 页面中有一个表单和一个文本框。
我正在尝试在 Button 的事件处理程序中访问我在 C# 中动态创建的 TextBox。 void MainFormLoad(object sender, EventArgs e)
我有一个搜索栏,当我打开搜索栏时,我想立即开始输入,不想点击文本框。 我尝试使用 myTextBoxId.click()(因为当您单击它时,您可以开始输入)但它不起作用。 最佳答案 你必须 docum
我还没有找到好的解决方案:我有一个文本框,用户需要能够在其中输入特定 信息。例如,命令可能是“9030 OUT FU [1234 TEST]”。我需要“擦洗”这个文本框以确保数据是以这种格式输入的(不
我有一个 Java 应用程序,您可以在其中将字符串输入文本框,点击加密,它会在单独的文本框中显示加密的字符串。我将为此使用 AES 加密。问题是我无法让加密文本按字节显示,但文本框不会显示字节(仅采用
我已经浏览了您庞大的问题数据库,但似乎没有找到答案。我在将文本换行时遇到问题 - 即使之前的行上仍有空间。这是代码: p1 { border-left: 6px solid blue; bac
所以我正在尝试创建“看板/待办事项列表”网站,但我在触发添加按钮时遇到了问题。我试图触发“添加”按钮以打开用户输入框。所以我有这个创建一个小框的“添加”按钮。但我无法弄清楚如何在该框中添加一个小区域,
我有一个文本框,应该只接受浮点值。它不应该允许任何其他值。怎么做。我在 HTML 中完成了此操作。 Weight 但是,它不起作用?如何做到这一点。 最佳答案 // remo
当用户点击文本框时,如何不显示出现在文本框下方的已填充值 最佳答案 将这个属性放在你的文本框中 autocomplete="off" 关于javascript - 文本框 - 如何不显示已填充的值,我
JavaScript: function resize(elem){ if(!elem.value.length) elem.size=1; else elem.size=elem.value
在我的代码下面,我需要它具有相同的宽度和高度,但有多行“从第一行开始”,当到达行尾时转到新行,只有 120 个字符,就像我用“Enter短信”当您向右单击时隐藏,但我需要它为灰色。 最佳答案 您可以使
我有一个问题,我必须创建一种方法来搜索显示在多个文本框 (lblResult.Text) 中的选定文本文件的内容。使用简单的搜索算法:搜索用户输入的整个搜索词。例如,如果用户输入“hello”,则只搜
我正在尝试对文本框使用 SelectionStart 和 SelectionLength 属性。它没有效果,但也没有错误。它实际上是后台工作程序 ProgressChanged 方法的一部分,但我已经
我是一名优秀的程序员,十分优秀!