首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >具有大量并行任务的WPF GUI性能

具有大量并行任务的WPF GUI性能
EN

Stack Overflow用户
提问于 2016-12-14 10:35:31
回答 3查看 424关注 0票数 0

我开发了一个小客户端(WPF)来对我们的系统进行一些压力测试。本质上,它必须并行地调用Asp.Net WebApi端点上的各种方法。

每次按下"Start“,它都会生成4000个任务(异步等待),同时请求压力,等待直到它们全部完成,然后再这样做-直到用户单击停止按钮。GUI使用进度条和一些计数器进行修饰:错误的请求、已完成的请求、正在进行的请求。我获得这些信息是因为发出一批压力请求的对象公开了一些事件:

代码语言:javascript
代码运行次数:0
运行
复制
var stressTestTask = new stressTestTask(LogService, configuration);

stressTestTask.ErrorRequestCountChanged += stressTestTask_ErrorRequestCountChanged;
stressTestTask.GoodRequestCountChanged += stressTestTask_GoodRequestCountChanged;
stressTestTask.TryRequestCountChanged += stressTestTask_TryRequestCountChanged;

_executionCancellationToken = new CancellationTokenSource();

await Task.Run(
    () => stressTestTask.ApiStressTestTask(_executionCancellationToken.Token),
    _executionCancellationToken.Token);

整个执行是从一个ICommand (MVVM)开始的:

代码语言:javascript
代码运行次数:0
运行
复制
private RelayCommand _startCommand;
public RelayCommand StartCommand
{
    get
    {
        return _startCommand ?? (_startCommand = new RelayCommand(
            async () =>
            {
                await StartStressTest();
            }));
    }
}

RelayCommand是库Mvvm-LightICommand的一个实现。

我不明白的是这种行为:如果我用“低”数量的任务配置我的批任务,例如2000年,GUI在执行时不会冻结。如果我选择5000项任务,过一段时间它就会结冰。如果打开客户端的.exe的另一个实例,并在每个实例上选择2000,则GUI在这两个方面都具有响应性。

我的第一个问题是:为什么用x任务打开一个实例在响应性方面比用x/n任务打开n实例更糟糕?这是否与Windows Scheduler有关,以及在第一种情况下,我只有一个进程?

我的第二个问题是:如何解决这个问题,使一切都在一个GUI上工作?我考虑用一批压力测试创建一个控制台应用程序,并从GUI中为我想要的每个实例调用一个命令,以便为每个批生成一个进程。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-12-14 10:43:48

您是否通过调用UI上下文来处理这些API事件?如果有许多调用发生,您将向调度程序注入大量操作,并导致UI挂起并落后于用户输入。

尝试批量更新UI。

票数 1
EN

Stack Overflow用户

发布于 2016-12-14 12:50:07

我的第一个问题是:为什么用x任务打开一个实例比用x/n任务打开n个实例更糟糕?

可能是因为在UI线程上要处理更多的事件。我想您的ErrorBetCountChanged、GoodRequestCountChanged和TryRequestCountChanged事件处理程序是在UI线程上调用的,引发的许多事件可能会淹没UI线程。

作为Gusdor sugget,您可能会找到一种批量更新的方法。看看反应性扩展(Rx):WhyRx.html

它有一个可能派上用场的缓冲区方法:TimeShiftedSequences.html

它还有en Obervable.FromEvent方法,您可以使用它将事件转换为IObservable:https://msdn.microsoft.com/en-us/library/hh229241(v=vs.103).aspx

我的第二个问题是:如何解决这个问题,使一切都在一个GUI上工作?

您需要找到一种方法-一种或指定者-更新UI的频率较低。批处理更新和事件应该是一个很好的起点。另一种选择是增加较少的通知。也许你需要两者兼得。

票数 1
EN

Stack Overflow用户

发布于 2016-12-14 10:57:02

我如何解决这个问题,使一切都在一个GUI上工作呢?

以“适当的”异步方式发送API请求--等待方式只有一个线程。

代码语言:javascript
代码运行次数:0
运行
复制
private async Task SendStressRequests()
{
    var tasks = new List<Task>();
    for (int i = 0; i < 4000; i++)
    {
        var task = SendApiRequestAsync();
        tasks.Add(task);
    }

    await Task.WhenAll(tasks);
    // Update UI with results
}    
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41140414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档