private void fly(CanvasRenderingContext2D ctx, double i, ToolStripStatusLabel label) { ElapsedEventHandler inner = delegate { bool isLocked = !Monitor.TryEnter(sync); if (!isLocked) { i++; ctx.fillStyle = "white"; ctx.fillRect(-1500, -1500, 3000, 3000); ctx.save(); ctx.translate(0, Math.Cos(i*0.1)*40); double a = Math.Sin(i*0.1); // right wing ctx.save(); ctx.rotate(Math.PI*0.4); wing(ctx, 18, a); ctx.restore(); // left wing ctx.save(); ctx.scale(-1, 1); ctx.rotate(Math.PI*0.4); wing(ctx, 18, a); ctx.restore(); // tail ctx.save(); tail(ctx, 20, Math.Sin(i*0.05)); ctx.restore(); // head neck(ctx, 22); ctx.restore(); ManagedBackBuffer.Render(_g); _g.Flush(FlushIntention.Sync); framesCount++; Monitor.Exit(sync); } }; timer = new Timer(); timer.Interval = interval; timer.Elapsed += inner; timer.Enabled = true; var counter = new Timer(); counter.Interval = 1000; counter.Elapsed += delegate { label.Text = "fps: " + framesCount + " / " + 1000/interval; lock (sync) { framesCount = 0; } }; counter.Enabled = true; }