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);
         }
     }