问题描述
我想在这是从另一个线程异步接收输入的形式来绘制。输入处理消耗大量的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 DataTrigger
s, 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 Square
s 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.
这篇关于实现形式好画刷新率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!