我已经实现了一个简单的多线程Server \ Client游戏作为我学院的作业。
客户端的除主线程外还有:
1-thread,负责在表格上绘制比赛场地和球员。
2线程与服务器通信以发送指示并接收位置和其他信息。
首先我使用了invoke技术,但它没有用,因为我在处理后使用了Graphics。见Draw on a form by a separate thread
所以为了避免这种情况并规范绘图线程,我只是在绘图线程上的每个特定时间提出标记'Invalidate'并将其实际处理留给主线程:
public Form1()
{
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
InitializeComponent();
}
private void Draw()
{
while (true)
{
Thread.Sleep(200);
Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (map.hasGraph)
{
map.Draw(e.Graphics);
if (this.Index != null)
e.Graphics.FillRectangle(Brush, Rectangle);
if (OpponentIndex != null)
e.Graphics.FillRectangle(OpponentBrush, OpponentRectangle);
}
}
这里的问题是,即使我正在使用双缓冲,表单也会以任意方式闪烁,当我增加绘图线程的休眠时间时,闪烁会减少,但我认为200ms已经太多了。 有什么建议吗?
[编辑]
我意识到我正在从代码和属性编辑器中设置双缓冲标志,这会产生问题(这可能是一个愚蠢的想法)但我花了半个小时用其中一个标志测试我的代码他们两个,当我从两个地方设置双缓冲标志时引发的问题,我的问题已经解决,但现在我需要知道这是否可以解决它。
答案 0 :(得分:2)
它运行的时间越长越糟越好?
每次你的程序绘制它时都会启动draw,它有一个无限循环,它调用paint,在另一个无限循环中调用draw。你似乎在这里有一个循环引用。如果我可以假设Map.Draw是私有的void Draw()
有一个更简单的解决方案,将所有内容绘制到位图,然后在onPaint事件中绘制bitpmap。
Bitmap buffer=new Bitmap(this.Width, this.Height); //make sure to resize the bitmap during the Form.Onresize event
Form1()
{
InitializeComponent();
Timer timer=new Timer();
timer.Interval= 100;
timer.Tick+=......
timer.Start()
}
//the Timer tick event
private void timer_tick(....
{
if (map.hasGraph)
{
using (Graphics g = Graphics.FromImage(buffer))
{
//You might need to clear the Bitmap first, and apply a backfround color or image
//change color to whatever you want, or don't use this line at all, I don't know
g.Clear(Color.AliceBlue);
if (this.Index != null)
g.FillRectangle(Brush, Rectangle);
if (OpponentIndex != null)
g.FillRectangle(OpponentBrush, OpponentRectangle);
}
panel1.BackgroundImage=buffer;
}
}
注意我没有对此语法准确性进行测试。
答案 1 :(得分:0)
对于执行的操作,系统的内存可能非常低。 阅读更多相关信息。 http://msdn.microsoft.com/en-us/library/system.drawing.graphics.aspx
答案 2 :(得分:0)