C# 如何暂停代码以完成其他代码,然后继续
我想做一个人工智能,让它像一个玩家一样。当它不知道该做什么时,它将执行随机移动,我称之为C# 如何暂停代码以完成其他代码,然后继续,c#,.net,wpf,dllimport,C#,.net,Wpf,Dllimport,我想做一个人工智能,让它像一个玩家一样。当它不知道该做什么时,它将执行随机移动,我称之为rndPlay()它将随机选择要单击的位置。它可以从9个位置中选择按1(),按2()等。我重复它,直到它连续按下两个按钮。现在问题来了 当for循环执行时,我告诉它按下850,400,那里有一个按钮,所以让我们调用btn1,它执行btnPressed1(),例如,我看到鼠标移动到那里并单击,但它不执行btnPressed1()。相反,它单击下一个随机位置并不断重复10000次,因为它没有成功移动(它必须按特定
rndPlay()代码>它将随机选择要单击的位置。它可以从9个位置中选择<编码>按1()
,按2()代码>等。我重复它,直到它连续按下两个按钮。现在问题来了
当for循环执行时,我告诉它按下850,400,那里有一个按钮,所以让我们调用btn1
,它执行btnPressed1()代码>,例如,我看到鼠标移动到那里并单击,但它不执行btnPressed1()代码>。相反,它单击下一个随机位置并不断重复10000次,因为它没有成功移动(它必须按特定顺序按两个按钮)。然后,当它退出for循环时,它执行btnPressed1()代码>。我不希望它在停止后执行此操作,因为每个按钮的顶部都是另一个按钮,让我们调用它btnMove1
,其编号与下面的按钮对应。例如,它按下了按钮1、1和8,在按下btn1
后应该显示btnMove1
,但由于它不会立即执行,所以它再次按下btn1
(不是btnMove1
),然后按下btn8
,然后在完成后执行btnPressed1()代码>然后btnPressed1()代码>一次又一次,最后btnPressed8()代码>我如何让它在按下下一步之前执行它按下的代码
我尝试使用Thread.Sleep(100)
使其停止,但它只是等待,不执行刚刚按下的按钮。我还使用if语句创建了自己的for循环,因为我认为可能是for循环停止了输入的执行
XAML代码:
<button x:Name="btn1" Click="btnPressed1"/>
<button x:Name="btnMove1" Click="btnMove1" Visibility="Hidden"/>
<button x:Name="btn2" Click="btnPressed2"/>
<button x:Name="btnMove2" Click="btnPressedMove2" Visibility="Hidden"/>
<button x:Name="btn3" Click="btnPressed3"/>
<button x:Name="btnMove3" Click="btnMove3" Visibility="Hidden"/>
//etc
//等
C#代码:
private void btnPressed1(对象发送方,路由目标)
{
btnMove1.Visibility=可见性.Visibility
}
私有无效btnPressed2(对象发送方,路由目标)
{
btnMove2.Visibility=可见性.Visibility
}
//等
私有无效btnPressedMove1(对象发送方,路由目标)
{
//一些代码
}
私有无效btnPressedMove2(对象发送方,路由目标e)
{
//一些代码
}
//等
私有无效移动到(整数x,整数y)
{
鼠标事件(MOUSEEVENTF_绝对| MOUSEEVENTF_移动,x,y,0,0);
}
[DllImport(“user32.dll”,CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
公共静态外部无效鼠标事件(uint-dwFlags、uint-dx、uint-dy、uint-cButtons、uint-dwExtraInfo);
//鼠标动作
private const int MOUSEEVENTF_LEFTDOWN=0x02;
private const int MOUSEEVENTF_LEFTUP=0x04;
private const int MOUSEEVENTF_RIGHTDOWN=0x08;
private const int MOUSEEVENTF_RIGHTUP=0x10;
[DllImport(“user32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
私有外部布尔设置游标(uint X,uint Y);
私有无效左鼠标单击(uint X,uint Y)
{
SetCursorPos(X,Y);
//使用光标的当前值调用导入的函数
鼠标事件(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP,X,Y,0,0);
睡眠(1000);
返回;
}
私人新闻1()
{
LeftMouseClick(2800025000);
最近2次移动(“1”);
}
私人新闻组2()
{
LeftMouseClick(33000025000);
最后2次移动(“2”);
}
//等
私有void rndPlay()
{
for(int r=0;movesuccess!=true&&r<10000;r++)
{
随机rndP=新随机();
int rndPress=rndP.Next(1,10);
如果(rndPress==1)
{
按1();
}
如果(rndPress==2)
{
按2();
}
//等
}
}
我希望它首先执行btnPressed1()代码>在按下下一步按钮之前,但它会保存所按下的内容,直到完成代码。如何使其在按下下一步之前完成代码?具有GUI的应用程序是事件驱动的。所有用户操作(以及一些其他事件)都被发布到消息队列,并由消息循环逐个处理。您可以阅读以下内容了解一些背景信息:
如果编写的代码与for循环类似,执行时间很长,则会阻止此消息循环处理任何事件
避免阻塞消息循环的一种方法是将rndPlay重写为异步方法:
private async Task rndPlay()
{
for (int r = 0; moveSucces != true && r < 10000; r++)
{
Random rndP = new Random();
int rndPress = rndP.Next(1, 10);
if (rndPress == 1)
{
press1();
}
if (rndPress == 2)
{
press2();
}
//etc
await Task.Delay(1000);
}
}
private异步任务rndPlay()
{
for(int r=0;movesuccess!=true&&r<10000;r++)
{
随机rndP=新随机();
int rndPress=rndP.Next(1,10);
如果(rndPress==1)
{
按1();
}
如果(rndPress==2)
{
按2();
}
//等
等待任务。延迟(1000);
}
}
这会在每次wait
时暂停rndPlay
的执行,并在1000毫秒延迟后将继续执行的方法发送到消息队列。这样,消息队列上的其他事件就有机会被消息循环处理
请注意,示例代码没有显示rndPlay
的调用者。您可能还需要在那里进行一些更改。MSDN声明:不要依赖wait Task.Yield();保持UI的响应性,但我同意异步编程可能是一个很好的起点
private async Task rndPlay()
{
for (int r = 0; moveSucces != true && r < 10000; r++)
{
Random rndP = new Random();
int rndPress = rndP.Next(1, 10);
if (rndPress == 1)
{
press1();
}
if (rndPress == 2)
{
press2();
}
//etc
await Task.Delay(1000);
}
}