我开始尝试向Windows窗体添加进度条,以更新在Parallel.Foreach循环中运行的代码的进度.为此,UI线程必须可用于更新进度条.我使用Task来运行Parallel.Foreach循环以允许UI线程更新进度条.
在Parallel.Foreach循环中完成的工作相当密集.在使用Task运行程序的可执行文件(不在visual studio中调试)之后,程序没有响应.如果我在没有Task的情况下运行程序,情况就不是这样.我在两个实例之间注意到的关键区别是,在没有Task的情况下运行时程序需要大约80%的cpu,在使用Task运行时大约需要5%.
private void btnGenerate_Click(object sender, EventArgs e)
{
var list = GenerateList();
int value = 0;
var progressLock = new object ();
progressBar1.Maximum = list.Count();
Task t = new Task(() => Parallel.ForEach (list, item =>
{
DoWork ();
lock (progressLock)
{
value += 1;
}
}));
t.Start();
while (!t.IsCompleted)
{
progressBar1.Value = value;
Thread.Sleep (100);
}
}
Run Code Online (Sandbox Code Playgroud)
旁注:我知道
Interlocked.Increment(ref int___);
Run Code Online (Sandbox Code Playgroud)
用来代替锁.它被认为更有效吗?
我的问题有三个方面:
1.)当负载少得多时,为什么带有Task的程序会无响应?
2.)使用Task运行Parallel.Foreach是否将Parallel.Foreach的线程池限制为只运行任务的线程?
3.)有没有办法让UI线程响应而不是在没有使用取消令牌的情况下休眠.1秒的持续时间?
我很感激任何帮助或想法,我花了很多时间研究这个.如果我违反任何发布格式或规则,我也会道歉.我试图坚持他们,但可能错过了一些东西.
我创建了一个简单的窗体,当您运行它时会弹出一个对话框,但无法以编程方式将其关闭。有人可以帮我吗?
Label lb = new Label();
Form frm = new Form();
lb.Left = 100;
lb.Top = 44;
frm.Controls.Add(lb);
frm.ShowDialog();
System.Threading.Thread.Sleep(2000);
Run Code Online (Sandbox Code Playgroud)
..Sleep(2000)之后,我希望它关闭。我试过了:
frm.close();frm.dispose();frm.visible = false;
Run Code Online (Sandbox Code Playgroud)
提前致谢!
我一直在尝试创建一个写入数据库的任务,而不会阻塞UI线程。我遇到的最大问题是等待该过程完成而不会发生阻塞。
我一直在尝试避免使用DoEvents(尽管此程序现在经常使用它,但我希望在前进时不再使用它)。
我试图创建要在第二个线程上运行的进程,并等待它完成以及使用BackgroundWorker。
我遇到的问题不是让代码在其他线程中运行,而是试图找到一种方法来等待它完成。
基本上,现在我要执行以下操作:
BackgroundWorker所以我可以使用ReportProgressBackgroundWorkerBackgroundWorker完成。对于线程,我等待IsAlive变为false,对于BackgroundWorker,我切换一个布尔变量。问题出在#4中。
在没有代码的情况下执行while循环,或者Thread.Sleep(0)阻塞UI(Thread.Sleep(0)使程序也占用程序资源的100%)
所以我做:
while (!thread.IsAlive)
Thread.Sleep(1);
Run Code Online (Sandbox Code Playgroud)
-要么-
while (bProcessIsRunning)
Thread.Sleep(1);
Run Code Online (Sandbox Code Playgroud)
这会阻塞用户界面。
如果在此调用Application.DoEvents(),则UI会更新(尽管它是可单击的,所以在此过程运行时,我必须禁用整个表单)。
如果我同步运行该过程,那么我仍然需要创建某种方式来更新UI(在我看来,是一个DoEvents调用),这样它就不会被锁定。
我究竟做错了什么?
我知道这个问题可能没有意义,而且我正在努力想办法解释它,所以我将展示一段代码来帮助.我在visual studio express 2010上使用Winforms:
private void button1(object sender, EventArgs e)
{
txtOutput.Text += "Auto-collecting variables. This may take several minutes";
string v = foo();
txtOutput.Text += "\n" + v;
string b = bar();
txtOutput.Text += "\n" + b;
txtOutput.SelectionStart = txtOutput.Text.Length;
txtOutput.ScrollToCaret(); //scrolls to the bottom of textbox
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,当用户点击button1时,我希望"自动收集变量..."显示在文本框中,然后让foo()执行,显示它,然后执行bar(),然后显示.
当前正在发生的是foo()和bar()执行,然后在执行foo()和bar()之后一切都显示(需要几分钟的函数).无论如何要解决这个问题,还是有解决方法?
编辑:C#的版本是4.0.如果我更新到4.5或5.0,没有.NET 4.5/5.0的计算机能够运行.exe吗?
using System.Windows.Forms;
public class App
{
[STAThread]
public static void Main()
{
string fname;
using (var d = new OpenFileDialog())
{
if (d.ShowDialog() != DialogResult.OK)
{
return;
}
fname = d.FileName;
}
//Application.ExitThread();
for (; ;)
;
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码显示了一个文件对话框.一旦我选择了一个文件并按下open,就会执行for循环,但是(冻结的)对话框仍然存在.
取消注释后Application.ExitThread(),对话框会按预期消失.
这是否按预期工作?为什么不让using窗户消失?我在哪里可以找到更多关于此的信息?
我这样做:
clear();
coinRefundComplete.Visible = true;
state = 0;
System.Threading.Thread.Sleep(4000);
clear();
greeting.Visible = true;
rate.Visible = true;
refundTicket.Visible = true;
currentTime.Visible = true;
Run Code Online (Sandbox Code Playgroud)
我希望coinRefundCompleteText(它是一个标签)出现4秒钟,然后通过我用clear()定义的方法清除,然后发生其他一些事情.相反,在我用第一个clear()清除我的表单后,我的表单空白4秒,然后正确完成.
只是一个快速的.我有一个问题,我创建了一个简单的工具,它使用一个小框来获取CPU使用一段时间,看起来显示正在使用的CPU的百分比(我已经删除了以下代码的GUI) ).
function loop
{
$get = read-host
for($start = 0; $start -le 100;$start++)
{
cls
$pro_percentage = Get-WmiObject win32_processor -computer $get -property Loadpercentage | select loadpercentage
$percentage = "Processor usage is: " + $pro_percentage.loadpercentage + "%"
$percentage
}
}
loop
Run Code Online (Sandbox Code Playgroud)
我已经创建了GUI的其他一些位,但我注意到了一个主要问题,这适用于我创建的其他GUI应用程序.每当按下"go"按钮从对话框启动脚本时,GUI就会冻结.我在GUI中创建的菜单栏冻结,没有其他按钮可以按下.
我应该在不同的线程中运行每个函数吗?那样的东西?
谢谢
我有一个表单,在单击按钮时打开另一个表单.当新表单打开时,我通过循环完成了一个进度条,然后我希望表单关闭.这是启动新表单的按钮单击事件.
private void calculateButton_Click(object sender, EventArgs e)
{
if (checkFormComplete())
{
ProgressForm proForm = new ProgressForm();
proForm.Show();
}
}
Run Code Online (Sandbox Code Playgroud)
以下是完成进度条的新表单的代码,该进度条应该自行关闭.
public ProgressForm()
{
InitializeComponent();
for (int i = 0; i < 101; i++)
calculationProgress.Value = i;
this.Close();
}
Run Code Online (Sandbox Code Playgroud)
但是,运行这个我得到:
无法访问已处置的对象.对象名称:'ProgressForm'.
调试器指向我的主窗体的这一行:
proForm.Show();
Run Code Online (Sandbox Code Playgroud)
我不确定我理解为什么,或者正确的方法是什么.在我的新表单中的close语句之后如何调用该行?
我试图WPF在动画完成时为一些东西设置动画并运行一些其他操作。
另外,想避免动画完成回调机制,所以,我想出了一个解决方案,如下面的代码所示:
// Start one second of animation
...
// Pause for one second
Wait(this.Dispatcher, 1000);
// Continue and do some other stuff
...
Run Code Online (Sandbox Code Playgroud)
现在,有趣的部分是Wait方法,它神奇地使我的代码中的阻塞暂停,但动画和 UI 保持正常、响应:
public static void Wait(Dispatcher Dispatcher, int Milliseconds)
{
var Frame = new DispatcherFrame();
ThreadPool.QueueUserWorkItem(State =>
{
Thread.Sleep(Milliseconds);
Frame.Continue = false;
});
Dispatcher.PushFrame(Frame);
}
Run Code Online (Sandbox Code Playgroud)
我已经阅读了有关文档和几篇文章,DispatcherFrame但我仍然无法弄清楚幕后真正发生了什么,我需要澄清一下这种结构是如何PushFrame真正起作用的。
我正在将C++应用程序转换为C#,我在代码库中的许多地方遇到过这一行代码:
Application->ProcessMessages()
Run Code Online (Sandbox Code Playgroud)
我找到了这个链接:http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Forms_TApplication_ProcessMessages.html
其中说ProcessMessages()的如下:
调用ProcessMessages以允许应用程序处理当前在消息队列中的消息.ProcessMessages循环Windows消息循环,直到它为空,然后将控制权返回给应用程序.
但什么是"消息",什么是"消息队列"?如何添加消息?进行了哪种处理?
我似乎无法找到任何具体的解释,这是什么,这很重要,因为我不知道这个方法调用的C#/ .NET等价物,或者它是某种形状或方式的功能烘焙到.NET,我不需要做任何事情?
使用C#标记了问题,因为我对它的.NET等价物最感兴趣,但该线程的真正意图仅仅是了解C++的作用.