C#OutofrangeException应该是不可能的
我有一些代码(如下所示),该代码在不同的线程上运行,并在其他任何可能在此处干扰它的地方都没有引用变量 i 。我只是不明白导致此错误的情况,我将一些观察者放在视觉工作室代码上,并且这些值似乎都很好,但几乎随机地无处可获得这个错误。
尽管我最好的知识完全与之隔绝了,但这是否可能是由代码的另一部分引起的?我什至将 i 的所有其他用途重命名为不同的字母,但我仍然遇到了这个问题。
这只是 for loops 的东西吗?
我是否以某种方式修改 i 甚至不知道吗?
这是完整的代码:
using SFML.Graphics;
using SFML.Window;
using System.Diagnostics;
using System.Numerics;
namespace RenderEngine
{
public class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
PhysicsEngine re = new PhysicsEngine();
for (int i = 0; i < 100; i++)
{
Debug.WriteLine(i);
}
}
}
public class PhysicsEngine
{
Solver solver = new Solver();
public void RenderEngine2()
{
ContextSettings settings = new ContextSettings();
settings.AntialiasingLevel = 8;
RenderWindow window = new RenderWindow(new VideoMode(2000, 1000), "Poop", Styles.Default, settings);
SFML.Graphics.Color color = new SFML.Graphics.Color(0, 0, 0, 0);
window.SetVerticalSyncEnabled(true);
CircleShape shape = new CircleShape(5);
shape.FillColor = new SFML.Graphics.Color(0, 0, 255, 255);
window.Closed += handelclose;
int drawcount = 0;
while (window.IsOpen)
{
window.Clear(color);
window.DispatchEvents();
try
{
foreach (Partical partical in solver.Particals)
{
shape.Position = new SFML.System.Vector2f((partical.position.X), (partical.position.Y));
window.Draw(shape);
drawcount++;
}
drawcount = 0;
}
catch
{
Debug.WriteLine("notready yet");
}
window.Display();
}
void handelclose(object sender, EventArgs e)
{
window.Close();
Environment.Exit(Environment.ExitCode);
}
}
List<Partical> todraw = new List<Partical>();
void EngineLoop()
{
while (true)
{
foreach (Partical partical in solver.Particals)
{
int x = (int)Math.Round(partical.position.X/10);
int y = (int)Math.Round(partical.position.Y/10);
List<int> ts = solver.Grid[x, y];
if (ts != null)
{
for (int brokenint = 0; brokenint < ts.Count; brokenint++)
{
Debug.WriteLine(partical.ID);
Debug.WriteLine(ts[brokenint]);
if (partical.ID != ts[brokenint])
{
Vector2 pos = new Vector2(partical.ID, ts[brokenint]);
if (solver.Collision.Count > 0)
{
if (!solver.Collision.Contains(pos))
solver.Collision.Add(pos);
}
else
{
solver.Collision.Add(pos);
}
}
}
}
}
}
}
private int particalcount = 10;
bool canstart = false;
public PhysicsEngine()
{
Parallel.Invoke(() =>
{
while (!canstart) { Thread.Sleep(100); }
Debug.WriteLine("third thread");
RenderEngine2();
},
() =>
{
while (!canstart) { Thread.Sleep(100); }
Debug.WriteLine("engine started");
EngineLoop();
},
() =>
{
Debug.WriteLine("first thread");
PhysicsLoop(this);
}
);
}
void PhysicsLoop(PhysicsEngine PhyEng)
{
int frames = 0;
long second = 0;
PhysicsStart(PhyEng);
Thread.Sleep(1000);
Stopwatch sw = Stopwatch.StartNew();
solver.startupdate();
while (true)
{
sw.Start();
todraw = solver.Particals;
solver.update();
frames++;
if (second != (Stopwatch.GetTimestamp() / Stopwatch.Frequency))
{
second = (Stopwatch.GetTimestamp() / Stopwatch.Frequency);
Debug.WriteLine(frames);
frames = 0;
}
sw.Stop();
sw.Reset();
if (sw.ElapsedMilliseconds < 15)
Thread.Sleep(15 - (int)sw.ElapsedMilliseconds);
}
}
void PhysicsStart(PhysicsEngine phyeng)
{
for (int i = 0; i < 210; i++)
{
for (int j = 0; j < 110; j++)
{
solver.Grid[i,j] = new List<int>();
}
}
Random rand = new Random();
for (int i = 0; i < particalcount; i++)
{
Partical partical = new Partical();
partical.position = new Vector2(rand.Next(0, 2000), rand.Next(0, 1000));
partical.oldposition = partical.position;
partical.ID = i;
int x1 = (int)Math.Round((partical.position.X + 5) / 10);
int y1 = (int)Math.Round((partical.position.Y + 5) / 10);
int x2 = (int)Math.Round((partical.position.X - 5) / 10);
int y2 = (int)Math.Round((partical.position.Y - 5) / 10);
solver.Grid[x1, y1].Add(partical.ID);
solver.Grid[x2, y1].Add(partical.ID);
solver.Grid[x1, y2].Add(partical.ID);
solver.Grid[x2, y2].Add(partical.ID);
solver.Particals.Add(partical);
}
canstart = true;
}
}
public class Partical
{
public Vector2 position = new Vector2(0, 0);
public Vector2 oldposition = new Vector2(0, 0);
public Vector2 acceleration = new Vector2(0, 0);
Vector2 zero = new Vector2(0, 0);
public int ID = new int();
public void updatePosition(float sub)
{
Vector2 velocity = position - oldposition;
oldposition = position;
position = position + (velocity * 0.9f) + acceleration * sub;
acceleration = zero;
}
public void accelerate(Vector2 accel)
{
acceleration = acceleration + accel;
}
}
public class Solver
{
public List<Partical> Particals = new List<Partical>();
public List<Vector2> Collision = new List<Vector2>();
public List<int>[,] Grid = new List<int>[2100,1100];
public void update()
{
int subcount = 8;
float sub = 1f / (float)subcount;
for (int i = 0; i < subcount; i++)
{
applyGravity(sub);
updatePositions(sub);
for (int j = 0; j < Collision.Count; j++)
{
solvecolisions((int)Collision[j].X, (int)Collision[j].Y);
}
Collision.Clear();
}
}
public void startupdate()
{
applyGravity(0.5f);
updatePositions(0.5f);
applyGravity(0.5f);
updatePositions(0.5f);
}
void updatePositions(float sub)
{
foreach (Partical partical in Particals)
{
partical.updatePosition(sub);
int x1 = (int)Math.Round((partical.oldposition.X + 5) / 10);
int y1 = (int)Math.Round((partical.oldposition.Y + 5) / 10);
int x2 = (int)Math.Round((partical.oldposition.X - 5) / 10);
int y2 = (int)Math.Round((partical.oldposition.Y - 5) / 10);
Grid[x1,y1].Remove(partical.ID);
Grid[x2,y1].Remove(partical.ID);
Grid[x1,y2].Remove(partical.ID);
Grid[x2,y2].Remove(partical.ID);
x1 = (int)Math.Round((partical.position.X + 5) / 10);
y1 = (int)Math.Round((partical.position.Y + 5) / 10);
x2 = (int)Math.Round((partical.position.X - 5) / 10);
y2 = (int)Math.Round((partical.position.Y - 5) / 10);
Grid[x1,y1].Add(partical.ID);
Grid[x2,y1].Add(partical.ID);
Grid[x1,y2].Add(partical.ID);
Grid[x2,y2].Add(partical.ID);
}
}
void applyGravity(float sub)
{
float gravitystrangth = -0.1f;
foreach (Partical partical in Particals)
{
float a = partical.position.Y;
float b = partical.position.X;
b -= 1000;
a -= 500;
double angle = Math.Atan2(a, b);
float newA = gravitystrangth * (float)(Math.Sin(angle));
float newB = gravitystrangth * (float)(Math.Sin((Math.PI / 180) * 90 - angle));
Vector2 gravity = new Vector2(newB, newA);
partical.accelerate(gravity);
}
}
void solvecolisions(int id1, int id2)
{
Partical part = Particals[id1];
Partical part2 = Particals[id2];
if (part != part2)
{
Vector2 colisionaxis = part.position - part2.position;
float dist = colisionaxis.Length();
if (dist < 10)
{
Vector2 n = colisionaxis / dist;
float delta = 10 - dist;
part.position += 0.5f * delta * n;
part2.position -= 0.5f * delta * n;
}
}
}
public List<Partical> GetParticals()
{
return Particals;
}
}
}
I have some code (as shown below) that is run on a different thread with the variable i not being referenced anywhere else that could interfere with it here. I just don't understand what is happening to cause this error, I put some watchers down with Visual Studio Code and the values all seem to be fine and in range but almost randomly out of nowhere I will get this error.
Is it possible that this is caused by another section of code despite to my best knowledge being completely isolated from it? I even went as far to rename all other uses of i to different letters and I still get this problem.
Is it just something with for loops?
Am I somehow modifying i without even know it?
Here is the full code:
using SFML.Graphics;
using SFML.Window;
using System.Diagnostics;
using System.Numerics;
namespace RenderEngine
{
public class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
PhysicsEngine re = new PhysicsEngine();
for (int i = 0; i < 100; i++)
{
Debug.WriteLine(i);
}
}
}
public class PhysicsEngine
{
Solver solver = new Solver();
public void RenderEngine2()
{
ContextSettings settings = new ContextSettings();
settings.AntialiasingLevel = 8;
RenderWindow window = new RenderWindow(new VideoMode(2000, 1000), "Poop", Styles.Default, settings);
SFML.Graphics.Color color = new SFML.Graphics.Color(0, 0, 0, 0);
window.SetVerticalSyncEnabled(true);
CircleShape shape = new CircleShape(5);
shape.FillColor = new SFML.Graphics.Color(0, 0, 255, 255);
window.Closed += handelclose;
int drawcount = 0;
while (window.IsOpen)
{
window.Clear(color);
window.DispatchEvents();
try
{
foreach (Partical partical in solver.Particals)
{
shape.Position = new SFML.System.Vector2f((partical.position.X), (partical.position.Y));
window.Draw(shape);
drawcount++;
}
drawcount = 0;
}
catch
{
Debug.WriteLine("notready yet");
}
window.Display();
}
void handelclose(object sender, EventArgs e)
{
window.Close();
Environment.Exit(Environment.ExitCode);
}
}
List<Partical> todraw = new List<Partical>();
void EngineLoop()
{
while (true)
{
foreach (Partical partical in solver.Particals)
{
int x = (int)Math.Round(partical.position.X/10);
int y = (int)Math.Round(partical.position.Y/10);
List<int> ts = solver.Grid[x, y];
if (ts != null)
{
for (int brokenint = 0; brokenint < ts.Count; brokenint++)
{
Debug.WriteLine(partical.ID);
Debug.WriteLine(ts[brokenint]);
if (partical.ID != ts[brokenint])
{
Vector2 pos = new Vector2(partical.ID, ts[brokenint]);
if (solver.Collision.Count > 0)
{
if (!solver.Collision.Contains(pos))
solver.Collision.Add(pos);
}
else
{
solver.Collision.Add(pos);
}
}
}
}
}
}
}
private int particalcount = 10;
bool canstart = false;
public PhysicsEngine()
{
Parallel.Invoke(() =>
{
while (!canstart) { Thread.Sleep(100); }
Debug.WriteLine("third thread");
RenderEngine2();
},
() =>
{
while (!canstart) { Thread.Sleep(100); }
Debug.WriteLine("engine started");
EngineLoop();
},
() =>
{
Debug.WriteLine("first thread");
PhysicsLoop(this);
}
);
}
void PhysicsLoop(PhysicsEngine PhyEng)
{
int frames = 0;
long second = 0;
PhysicsStart(PhyEng);
Thread.Sleep(1000);
Stopwatch sw = Stopwatch.StartNew();
solver.startupdate();
while (true)
{
sw.Start();
todraw = solver.Particals;
solver.update();
frames++;
if (second != (Stopwatch.GetTimestamp() / Stopwatch.Frequency))
{
second = (Stopwatch.GetTimestamp() / Stopwatch.Frequency);
Debug.WriteLine(frames);
frames = 0;
}
sw.Stop();
sw.Reset();
if (sw.ElapsedMilliseconds < 15)
Thread.Sleep(15 - (int)sw.ElapsedMilliseconds);
}
}
void PhysicsStart(PhysicsEngine phyeng)
{
for (int i = 0; i < 210; i++)
{
for (int j = 0; j < 110; j++)
{
solver.Grid[i,j] = new List<int>();
}
}
Random rand = new Random();
for (int i = 0; i < particalcount; i++)
{
Partical partical = new Partical();
partical.position = new Vector2(rand.Next(0, 2000), rand.Next(0, 1000));
partical.oldposition = partical.position;
partical.ID = i;
int x1 = (int)Math.Round((partical.position.X + 5) / 10);
int y1 = (int)Math.Round((partical.position.Y + 5) / 10);
int x2 = (int)Math.Round((partical.position.X - 5) / 10);
int y2 = (int)Math.Round((partical.position.Y - 5) / 10);
solver.Grid[x1, y1].Add(partical.ID);
solver.Grid[x2, y1].Add(partical.ID);
solver.Grid[x1, y2].Add(partical.ID);
solver.Grid[x2, y2].Add(partical.ID);
solver.Particals.Add(partical);
}
canstart = true;
}
}
public class Partical
{
public Vector2 position = new Vector2(0, 0);
public Vector2 oldposition = new Vector2(0, 0);
public Vector2 acceleration = new Vector2(0, 0);
Vector2 zero = new Vector2(0, 0);
public int ID = new int();
public void updatePosition(float sub)
{
Vector2 velocity = position - oldposition;
oldposition = position;
position = position + (velocity * 0.9f) + acceleration * sub;
acceleration = zero;
}
public void accelerate(Vector2 accel)
{
acceleration = acceleration + accel;
}
}
public class Solver
{
public List<Partical> Particals = new List<Partical>();
public List<Vector2> Collision = new List<Vector2>();
public List<int>[,] Grid = new List<int>[2100,1100];
public void update()
{
int subcount = 8;
float sub = 1f / (float)subcount;
for (int i = 0; i < subcount; i++)
{
applyGravity(sub);
updatePositions(sub);
for (int j = 0; j < Collision.Count; j++)
{
solvecolisions((int)Collision[j].X, (int)Collision[j].Y);
}
Collision.Clear();
}
}
public void startupdate()
{
applyGravity(0.5f);
updatePositions(0.5f);
applyGravity(0.5f);
updatePositions(0.5f);
}
void updatePositions(float sub)
{
foreach (Partical partical in Particals)
{
partical.updatePosition(sub);
int x1 = (int)Math.Round((partical.oldposition.X + 5) / 10);
int y1 = (int)Math.Round((partical.oldposition.Y + 5) / 10);
int x2 = (int)Math.Round((partical.oldposition.X - 5) / 10);
int y2 = (int)Math.Round((partical.oldposition.Y - 5) / 10);
Grid[x1,y1].Remove(partical.ID);
Grid[x2,y1].Remove(partical.ID);
Grid[x1,y2].Remove(partical.ID);
Grid[x2,y2].Remove(partical.ID);
x1 = (int)Math.Round((partical.position.X + 5) / 10);
y1 = (int)Math.Round((partical.position.Y + 5) / 10);
x2 = (int)Math.Round((partical.position.X - 5) / 10);
y2 = (int)Math.Round((partical.position.Y - 5) / 10);
Grid[x1,y1].Add(partical.ID);
Grid[x2,y1].Add(partical.ID);
Grid[x1,y2].Add(partical.ID);
Grid[x2,y2].Add(partical.ID);
}
}
void applyGravity(float sub)
{
float gravitystrangth = -0.1f;
foreach (Partical partical in Particals)
{
float a = partical.position.Y;
float b = partical.position.X;
b -= 1000;
a -= 500;
double angle = Math.Atan2(a, b);
float newA = gravitystrangth * (float)(Math.Sin(angle));
float newB = gravitystrangth * (float)(Math.Sin((Math.PI / 180) * 90 - angle));
Vector2 gravity = new Vector2(newB, newA);
partical.accelerate(gravity);
}
}
void solvecolisions(int id1, int id2)
{
Partical part = Particals[id1];
Partical part2 = Particals[id2];
if (part != part2)
{
Vector2 colisionaxis = part.position - part2.position;
float dist = colisionaxis.Length();
if (dist < 10)
{
Vector2 n = colisionaxis / dist;
float delta = 10 - dist;
part.position += 0.5f * delta * n;
part2.position -= 0.5f * delta * n;
}
}
}
public List<Partical> GetParticals()
{
return Particals;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的ts列表取决于solver.grid [x,y]。我相信您的某些代码在屏幕上不可见会更改solver.grid,可能有时会删除或替换它们。这就是导致错误的原因。
You ts list depends on solver.Grid[x,y]. I am sure that some of your code that is not visible on the screen makes some changes of solver.Grid, probably deletes some times, or replaces them. This is what causing the error.