相关疑难解决方法(0)

在.NET 4.0中使用Task with Parallel.Foreach

我开始尝试向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秒的持续时间?

我很感激任何帮助或想法,我花了很多时间研究这个.如果我违反任何发布格式或规则,我也会道歉.我试图坚持他们,但可能错过了一些东西.

c# parallel-processing multithreading .net-4.0

4
推荐指数
1
解决办法
2133
查看次数

如何以编程方式关闭对话框

我创建了一个简单的窗体,当您运行它时会弹出一个对话框,但无法以编程方式将其关闭。有人可以帮我吗?

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)

提前致谢!

c#

4
推荐指数
2
解决办法
5686
查看次数

等待很长时间,仍在更新用户界面

我一直在尝试创建一个写入数据库的任务,而不会阻塞UI线程。我遇到的最大问题是等待该过程完成而不会发生阻塞。

我一直在尝试避免使用DoEvents(尽管此程序现在经常使用它,但我希望在前进时不再使用它)。

我试图创建要在第二个线程上运行的进程,并等待它完成以及使用BackgroundWorker

我遇到的问题不是让代码在其他线程中运行,而是试图找到一种方法来等待它完成。

基本上,现在我要执行以下操作:

  1. 连接到数据库
  2. 创建一个后台工作程序(或线程)来写数据库(我可能最终会写成,BackgroundWorker所以我可以使用ReportProgress
  3. 启动线程或 BackgroundWorker
  4. 使用While循环等待线程/ BackgroundWorker完成。对于线程,我等待IsAlive变为false,对于BackgroundWorker,我切换一个布尔变量。
  5. 我让用户知道该过程已完成。

问题出在#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调用),这样它就不会被锁定。

我究竟做错了什么?

.net c# multithreading doevents winforms

3
推荐指数
1
解决办法
1万
查看次数

如何在长时间运行的功能中更新UI(文本字段)?

我知道这个问题可能没有意义,而且我正在努力想办法解释它,所以我将展示一段代码来帮助.我在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吗?

c# .net-4.0 winforms

3
推荐指数
1
解决办法
4385
查看次数

我必须调用Application.ExitThread()吗?

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窗户消失?我在哪里可以找到更多关于此的信息?

.net c# mono dialog winforms

3
推荐指数
2
解决办法
601
查看次数

代码在线程休眠之前没有执行?

我这样做:

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秒,然后正确完成.

.net c# multithreading winforms

3
推荐指数
1
解决办法
549
查看次数

Powershell:冻结GUI

只是一个快速的.我有一个问题,我创建了一个简单的工具,它使用一个小框来获取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中创建的菜单栏冻结,没有其他按钮可以按下.

我应该在不同的线程中运行每个函数吗?那样的东西?

谢谢

powershell user-interface multithreading function

2
推荐指数
1
解决办法
7637
查看次数

不能使形式"靠近自己"?

我有一个表单,在单击按钮时打开另一个表单.当新表单打开时,我通过循环完成了一个进度条,然后我希望表单关闭.这是启动新表单的按钮单击事件.

    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语句之后如何调用该行?

c# visual-studio-2010 winforms

2
推荐指数
1
解决办法
4433
查看次数

WPF DispatcherFrame 魔法 - 它是如何以及为什么起作用的?

我试图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# wpf

2
推荐指数
1
解决办法
2457
查看次数

Application-> ProcessMessage有什么作用?

我正在将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++的作用.

c# c++

2
推荐指数
1
解决办法
5889
查看次数