我有特定的问题,我不知道如何解决它。我已经在winforms中制作了一个程序,它在Task中占用了所有的时间。它的工作几分钟就崩溃了。
private void TaskBot()
{
Task taskHeal = new Task(() =>
{
while (boolCheckBoxHP != null)
{
Thread.Sleep(200);
if (boolCheckBoxHP == true)
{
Bitmap bitmap;
try
{
bitmap = new
//THERE IS AN ERROR
Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
//THERE IS AN ERROR
Graphics graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message + "\n\nCause: " + "SpriteSet not yet loaded.");
bitmap = null;
}
KontrolujPoziomHP(bitmap);
if (bitmap != null) bitmap.Dispose();
}
if (boolCheckBoxMana == true)
{
Bitmap bitmap;
try
{
bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message + "\n\nCause: " + "SpriteSet not yet loaded.");
bitmap = null;
}
Thread.Sleep(50);
KontrolujPoziomMany(bitmap);
if (bitmap != null) bitmap.Dispose();
}
}
});
taskHeal.Start();
}
这是Visual Studio的错误:
The parameter is invalid
System.ArgumentException HResult = 0x80070057 Message =参数是 无效。 Source = System.Drawing Stack trace:in System.Drawing.Bitmap..ctor(Int32宽度,Int32高度,PixelFormat 在System.Drawing.Bitmap..ctor(Int32宽度,Int32高度)中的格式) C:\ Users \ Pawel \ source \中的TibiaHelper.Form1.CopyScreen(in) repos \ TibiaHelper \ TibiaHelper \ Form1.cs:第157行 TibiaHelper.Form1.Check C:\ Users \ Pawel \ source中的LevelHP() \ repos \ TibiaHelper \ TibiaHelper \ Form1.cs:第368行 C:\ Users \ Pawel \ source \ repos \中的TibiaHelper.Form1.b__22_0() TibiaHelper \ TibiaHelper \ Form1.cs:308行 System.Threading中的System.Threading.Tasks.Task.InnerInvoke()。 Tasks.Task.Execute()
答案 0 :(得分:1)
您的内存和/或连续地址空间不足。如果您使用的是32位进程,后者很有可能。完成后正确处理图形和位图应该有所帮助。如果屏幕大小没有改变,还要考虑重用相同的位图。屏幕大小的位图非常大。
以下代码将在30次迭代后与该异常一起崩溃。
for (int i = 0; i < 500; i++)
{
new Bitmap(5000, 5000);
}
这样就可以了,但这需要一段时间,而且非常浪费。
for (int i = 0; i < 500; i++)
{
new Bitmap(5000, 5000).Dispose();
}
更新:从您的编辑中我可以看到您没有丢弃图形对象。您还应该如此重复使用位图和图形
private async Task Foo(CancellationToken cancel)
{
using (var bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height))
using (var graphics = Graphics.FromImage(bitmap))
{
while (true)
{
cancel.ThrowIfCancellationRequested();
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size, CopyPixelOperation.SourceCopy);
ProcessImage(bitmap);
await Task.Delay(200);
}
}
}