简体   繁体   English

如何使用BeginInvoke

[英]How to use BeginInvoke

Ive got this problem: 我遇到了这个问题:

Line 20 (LOOT_FromContainer(container) I need that to use as Invoke , because the process I want to exec takes some time, so ServerMessageHandler won't handle it... 第20行(LOOT_FromContainer(容器)我需要将它用作Invoke ,因为我想要exec的进程需要一些时间,所以ServerMessageHandler将不会处理它...

If I just simply rewrite that line to LOOT_FromContainer.BeginInvoke(container); 如果我只是简单地将该行重写为LOOT_FromContainer.BeginInvoke(container); then I have this error: 然后我有这个错误:

error CS0119: 'LOOT.LOOT_FromContainer(Phoenix.Serial)' is a 'method', which is not valid in the given context 错误CS0119:'LOOT.LOOT_FromContainer(Phoenix.Serial)'是'方法',在给定的上下文中无效

I'm new to C#, came from PHP, and about Invoke I don't know much really. 我是C#的新手,来自PHP,关于Invoke我真的不太了解。 I've been trying to sort this out for a couple of days, not even google helped... 我一直试图解决这个问题几天,甚至谷歌帮助...

  [ServerMessageHandler(0x3C)]
  public CallbackResult ContainerContains(byte[] data, CallbackResult prevResult)
  {
     PacketReader reader = new PacketReader(data);
     reader.Skip(3);

     ushort len = reader.ReadUInt16();
     for (int i = 0; i < len; i++)
     {
        Serial serial = (Serial)(reader.ReadUInt32());
        ushort graphic = (ushort)(reader.ReadUInt16());

        reader.Skip(7);

        Serial container = (Serial)(reader.ReadUInt32());
        ushort color = (ushort)(reader.ReadUInt16());

        if (((int)graphic == 0x0E76) && ((int)color == 0x049A))
        {
           LOOT_FromContainer.BeginInvoke(container);
        }
     }
     return CallbackResult.Normal;
  }

  [Command]
  public static void LOOT_FromContainer(Serial target)
  {
        UOItem lootCorpse = new UOItem(target);
        if (lootCorpse.Graphic == 0x2006)
        {
            if (((draw == 1) && (World.Player.Backpack.AllItems.Count(draw_knife[0], draw_knife[1]) > 0)) || (World.Player.Layers[Layer.RightHand].Exist))
            {
                if ((lootCorpse.Amount != 400) && (lootCorpse.Amount != 401))
                {
                    if (draw == 0)
                    {
                        UO.WaitTargetObject(lootCorpse);
                        UO.UseObject(World.Player.Layers[Layer.RightHand].Serial);
                    }
                    else
                    {
                        UO.WaitTargetObject(lootCorpse);
                        UO.UseType(draw_knife[0], draw_knife[1]);
                    }
                    UO.Wait(500);
                }
            }
            else
        {
               UO.Print("Neni cim rezat, pouze lootim");
        }

            for (int i = 0; i < loot.Length; i++)
            {
           if (lootCorpse.Items.Count(loot[i][0], loot[i][1]) > 0)
                {
              if (loot[i][2] == 1)
              {
                 if (loot[i][4] == 1)
                 {
                    UO.MoveItem(lootCorpse.Items.FindType(loot[i][0], loot[i][1]), 0, Aliases.GetObject("loot_bag"), loot[i][5], loot[i][6]);
                      UO.Wait(200);
                 }
                 else
                 {
                    UO.MoveItem(lootCorpse.Items.FindType(loot[i][0], loot[i][1]), 0, World.Player.Backpack);
                        UO.Wait(200);
                 }
              }
                }
            }
        }
  }

I think this is what you need. 我想这就是你需要的。 You need to declare a delegate with the same return type and input parameters as your method, instantiate this delegate pointing it at your method and then call BeginInvoke on it passing in your serial variable, followed by null, null: 您需要声明一个具有与您的方法相同的返回类型和输入参数的委托,实例化该委托指向您的方法,然后调用BeginInvoke传入您的串行变量,然后是null,null:

public delegate void LFC(Serial target);

[ServerMessageHandler(0x3C)]
  public CallbackResult ContainerContains(byte[] data, CallbackResult prevResult)
  {
   PacketReader reader = new PacketReader(data);
   reader.Skip(3);

   ushort len = reader.ReadUInt16();
   for (int i = 0; i < len; i++)
   {
      Serial serial = (Serial)(reader.ReadUInt32());
      ushort graphic = (ushort)(reader.ReadUInt16());

      reader.Skip(7);

      Serial container = (Serial)(reader.ReadUInt32());
      ushort color = (ushort)(reader.ReadUInt16());

    LFC = lootfromcontainer = new LFC(LOOT_FromContainer);

      if (((int)graphic == 0x0E76) && ((int)color == 0x049A))
      {
        lootfromcontainer.BeginInvoke(container, null, null);
         //LOOT_FromContainer.BeginInvoke(container);
      }
   }
   return CallbackResult.Normal;
  }


[Command]
public static void LOOT_FromContainer(Serial target)
{
   UOItem lootCorpse = new UOItem(target);
      if (lootCorpse.Graphic == 0x2006)
      {
          if (((draw == 1) && (World.Player.Backpack.AllItems.Count(draw_knife[0], draw_knife[1]) > 0)) || (World.Player.Layers[Layer.RightHand].Exist))
          {
              if ((lootCorpse.Amount != 400) && (lootCorpse.Amount != 401))
              {
                  if (draw == 0)
                  {
                      UO.WaitTargetObject(lootCorpse);
                      UO.UseObject(World.Player.Layers[Layer.RightHand].Serial);
                  }
                  else
                  {
                      UO.WaitTargetObject(lootCorpse);
                      UO.UseType(draw_knife[0], draw_knife[1]);
                  }
                  UO.Wait(500);
              }
          }
          else
      {
             UO.Print("Neni cim rezat, pouze lootim");
      }

          for (int i = 0; i < loot.Length; i++)
          {
         if (lootCorpse.Items.Count(loot[i][0], loot[i][1]) > 0)
              {
            if (loot[i][2] == 1)
            {
               if (loot[i][4] == 1)
               {
                  UO.MoveItem(lootCorpse.Items.FindType(loot[i][0], loot[i][1]), 0, Aliases.GetObject("loot_bag"), loot[i][5], loot[i][6]);
                    UO.Wait(200);
               }
               else
               {
                  UO.MoveItem(lootCorpse.Items.FindType(loot[i][0], loot[i][1]), 0, World.Player.Backpack);
                      UO.Wait(200);
               }
            }
              }
          }
      }
}

If you simply need to run that in another thread you can use ThreadPool . 如果您只需要在另一个线程中运行它,您可以使用ThreadPool

For this you would need few easy things : 为此你需要一些简单的事情

Instead of: 代替:

LOOT_FromContainer.BeginInvoke(container);

You would use: 你会用:

ThreadPool.QueueUserWorkItem(LOOT_FromContainer, container);

And slightly modify your LOOT_FromContainer method to: 并稍微修改您的LOOT_FromContainer方法:

public static void LOOT_FromContainer(object prm)
{
   var target = (Serial)prm;
   // ...

I'm assuming LOOT_FromCotainer is a control, and given the error your compiler returns, one can roughly guess the problem is that you're calling BeginInvoke with a non-delegate. 我假设LOOT_FromCotainer是一个控件,并且在编译器返回错误的情况下,可以粗略地猜测问题是您正在使用非委托调用BeginInvoke。 BeginInvoke is called as follows: BeginInvoke的调用方式如下:

LOOT_FromContainer.BeginInvoke(container); //where container is a delegate that maybe declared as follows

private delegate void container; //may also contain parameters eg container(string s);

So just rework your code to follow in this manner. 因此,只需按照这种方式重新编写代码即可。 See this document for example on how to use BeginInvoke. 有关如何使用BeginInvoke的示例,请参阅此文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM