本文介绍了实现形式好画刷新率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在这是从另一个线程异步接收输入的形式来绘制。输入处理消耗大量的CPU时间。因此,我想设置为每秒约10次的东西刷新率,但我在努力取得这样的。我想知道你们的想法我可以做,以加快我的代码,如果有什么?我试图将其降低到这里的代码最简单的数量。一些代码最初是从网络上找到不同的应用程序复制的,所以我道歉,如果我离开多余的东西(随时告诉我的)。我可以尝试提供从申请抽象方法的详细代码



 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;使用System.Threading.Tasks
;
使用TagReader;
使用交互器;使用MathNet.Numerics.Distributions
;使用System.Runtime.CompilerServices
;
使用的System.Threading;使用System.Media
;
使用System.Drawing.Drawing2D;使用System.Windows.Forms的
;

命名空间RFIDInteraction
{
抽象类RFIDApplication:表
{


的DateTime lastTime = DateTime.Now;
INT refreshEllapse =(int)的十分之一千; //只有10毫秒已通过

刷新///<总结>
///必需的设计变量。
///< /总结>
私人System.ComponentModel.IContainer成分= NULL;


保护无效maybeRefresh()
{
如果((DateTime.Now - lastTime).Milliseconds> refreshEllapse)
{
this.Refresh();
lastTime = DateTime.Now;
}



}



[MethodImpl(MethodImplOptions.Synchronized)
私人无效InputWrapper(对象发件人,System.Collections.Specialized.NotifyCollectionChangedEventArgs E)
{

updateLoopStep(输入); //在此方法(未示出)代码执行根据所输入的一些更新 - 这可能是昂贵的


maybeRefresh();
}



#地区boringstuff
私人无效的InitializeComponent()
{
this.components =新System.ComponentModel 。容器();
this.SuspendLayout();

this.AutoScaleDimensions =新System.Drawing.SizeF(6F,13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize =新System.Drawing.Size(1000,1000);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.Name =应用程序;
this.Text =应用程序;
this.Load + =新System.EventHandler(this.LoadContent);
的SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw,真正的);
this.ResumeLayout(假);

}

#endregion

受保护的应用程序()
{

的InitializeComponent();

System.Collections.Specialized.NotifyCollectionChangedEventHandler inputCallback =
新System.Collections.Specialized.NotifyCollectionChangedEventHandler(InputWrapper);



新TagStatesThread(inputCallback); //线程在后台运行 - 可能是一个昂贵的过程

}


保护覆盖无效的Dispose(BOOL处置)
{
如果(设置&放大器;及(成分=空)!)
{
components.Dispose();
}
base.Dispose(处置);
}


保护无效LoadContent(对象发件人,EventArgs五)
{

this.SetStyle(
的ControlStyles。 AllPaintingInWmPaint |
ControlStyles.UserPaint |
ControlStyles.DoubleBuffer,
真);
this.UpdateStyles();

loadAllContent(); //用来加载图像资产,这样的(一次)

}


保护覆盖无效的OnPaint(PaintEventArgs的E)$ B $一些简单的方法(未显示) b {
base.OnPaint(E);

e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.Clear(背景色);

//此方法中(未显示)代码处理绘制所有图片 - 只是通过他们所有的迭代,并调用e.Graphics.DrawImage。可能要绘制大量图像(100)
displayNewState(e.Graphics)的;


}





}
}

另外,一个问题 - 当一个呼叫绘制而成,并没有什么必须做,这似乎画得更快 - 言下之意如果一个像素没有被改变,它消耗几乎可以忽略不计的处理时间(提示系统自动检查什么需要拉伸,是相当智能)。这是真的



编辑:一个示例应用程序的截图:




解决方案

好了的话,这是你会怎么做,在WPF:



步骤1:



创建一个小的数据模型将代表他们的正方形的井字游戏:

 公共枚举SquareValue 
{
空= 0,
X = 1,
O = 2
}

公共类广场:INotifyPropertyChanged的
{
私人SquareValue _value;
公共SquareValue价值
{
得到{_value; }

{
_value =值;
OnPropertyChanged();
}
}

公共事件PropertyChangedEventHandler的PropertyChanged;

受保护的虚拟无效OnPropertyChanged([CallerMemberName]字符串参数propertyName = NULL)
{
VAR处理器=的PropertyChanged;
如果(处理!= NULL)处理(这一点,新PropertyChangedEventArgs(propertyName的));
}
}

公共类游戏
{
公开名单<广场>广场{搞定;私人集; }

公共游戏()
{
this.Squares =
Enumerable.Range(0,9)
。选择(X =>新建广场{值= SquareValue.Empty})
.ToList();
}
}





步骤2:



使用,定义每个井字板会如何看这样的:

 <的ItemsControl的ItemsSource ={结合广场}保证金=5了borderThickness =1BorderBrush = DarkBlue> 
< ItemsControl.ItemsPanel>
< ItemsPanelTemplate>
< UniformGrid行=3列=3/>
< / ItemsPanelTemplate>
< /ItemsControl.ItemsPanel>

< ItemsControl.ItemTemplate>
<&DataTemplate的GT;
< BORDER BorderBrush =深灰了borderThickness =1>
<路径X:名称=路径拉伸=填充
保证金=2/>
< /边框>

<! - 未完待续... - >



Step 2:

Using an ItemsControl, define how each Tic Tac Toe board is going to look like:

<ItemsControl ItemsSource="{Binding Squares}" Margin="5" BorderThickness="1" BorderBrush="DarkBlue">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="3" Columns="3"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="DarkGray"  BorderThickness="1">
                <Path x:Name="Path" Stretch="Fill"
                      Margin="2"/>
            </Border>

            <!-- to be continued... -->

Step 3:

Using DataTriggers, we define how the square will look like depending on whether it's Empty, X, or O:

            <!-- continuation of the above XAML -->
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding Value}" Value="X">
                    <Setter TargetName="Path" Property="Stroke" Value="Red"/>
                    <Setter TargetName="Path" Property="Data" Value="M0,0 L10,10 M0,10 L10,0"/>
                </DataTrigger>

                <DataTrigger Binding="{Binding Value}" Value="O">
                    <Setter TargetName="Path" Property="Stroke" Value="Blue"/>
                    <Setter TargetName="Path" Property="Data">
                        <Setter.Value>
                            <EllipseGeometry RadiusX="10" RadiusY="10" Center="0.0,0.0"/>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Step 4:

We now have the XAML for each Tic Tac Toe board, let's now create some XAML to represent many boards, again, using another ItemsControl:

<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="10" Columns="10"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <!-- the above XAML for a single Tic Tac Toe board goes here -->
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Step 5:

Now we set our Window's DataContext to a list of our Game class:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        this.Loaded += (sender, args) =>
        {
            this.DataContext = Enumerable.Range(0,100)
                                         .Select(x => new Game())
                                         .ToList();
        };
    }
}

Step 6:

Using whatever method you desire, modify the Value property of the Squares so that they become X, or O. In this case since this is just a demo I'll use a Timer and set it randomly. Modify the Game class like so:

public class Game
{
    public List<Square> Squares { get; private set; }
    private Timer timer;
    private Random random = new Random();

    public Game()
    {
        this.Squares = Enumerable.Range(0, 9).Select(x => new Square {Value = SquareValue.Empty}).ToList();
        this.timer = new Timer(Callback, null, TimeSpan.FromSeconds(3), TimeSpan.FromMilliseconds(10));
    }

    private void Callback(object state)
    {
        var sq = Squares[random.Next(0, 9)];
        var value = random.Next(0, 3);
        sq.Value = (SquareValue) value;
    }
}

Result:

  • Rendering is immediate and there's absolutely no lag
  • UI is resolution independent and adjusts to the window size. You can try running this project and resizing the window to see how smooth it is.
  • The Data Model is completely decoupled from the UI and the UI does not need any sort of code behind hacks. It's just Simple, Simple Properties and DataBinding.
  • You can further customize the boards, Xs and Os to look however you want. WPF uses vector graphics which can be infinitely stretched without losing quality.
  • Total code in this sample is 25 lines of C# + some 40 lines of XAML. Much less than it would require to do something similar in winforms, and yet the result is much better.
  • Full source code on GitHub.
  • Forget winforms.

这篇关于实现形式好画刷新率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 15:43