简体   繁体   中英

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...

If I just simply rewrite that line to 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

I'm new to C#, came from PHP, and about Invoke I don't know much really. 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:

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 .

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:

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. BeginInvoke is called as follows:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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