none
YIELD - Erklärung RRS feed

  • Frage

  • Hallo,

    kann mir jemand sagen was die Vorteile hier sind?

    Warum while?

    YIELD

    // ** Wenn der State .Crawl gebe ich 0 zurück, sonst?
       IEnumerator CrawlState () 
    	{
    		Debug.Log("Crawl: Enter");
    
    		while (state == State.Crawl) 
    		{
    			yield return 0;
    		}
    		Debug.Log("Crawl: Exit");
    		NextState();
    	}

    Ist das FREE?

    UnityEngine

    und wo lade ich das herunter? Wie ist Eure Erfahrung damit?

    Download, Wo?

    Grüße Oliver

    ###################

        using UnityEngine;
        using System.Collections;
         
        public class Monster : MonoBehaviour {
         
            public enum State {
                Crawl,
                Walk,
                Die,
            }
         
            public State state;
         
            IEnumerator CrawlState () {
                Debug.Log("Crawl: Enter");
                while (state == State.Crawl) {
                    yield return 0;
                }
                Debug.Log("Crawl: Exit");
                NextState();
            }
         
            IEnumerator WalkState () {
                Debug.Log("Walk: Enter");
                while (state == State.Walk) {
                    yield return 0;
                }
                Debug.Log("Walk: Exit");
                NextState();
            }
         
            IEnumerator DieState () {
                Debug.Log("Die: Enter");
                while (state == State.Die) {
                    yield return 0;
                }
                Debug.Log("Die: Exit");
            }
         
            void Start () {
                NextState();
            }
         
            void NextState () {
                string methodName = state.ToString() + "State";
                System.Reflection.MethodInfo info =
                    GetType().GetMethod(methodName,
                                        System.Reflection.BindingFlags.NonPublic |
                                        System.Reflection.BindingFlags.Instance);
                StartCoroutine((IEnumerator)info.Invoke(this, null));
            }
           
        }

    Freitag, 4. Mai 2012 10:17

Antworten

  • Bei jedem Next des Enumerators wird mit Current das aktuelle Element geholt. Bei der Nutzung von yield wird erst in diesem Moment das Element wirklich bereitgestellt.
     
    Zum weiteren Verständnis kannst Du Dir mal die Zeitmessung in der folgenden Demo anschauen:
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Collections;
    using System.Threading;
    
    namespace ConsoleApplication1
    {
      class Program
      {
        static void Main(string[] args)
        {
          C1 c = new C1();
          Stopwatch sw = new Stopwatch();
          sw.Start();
          c.ArbeitOhneYield();
          Console.WriteLine("Arbeit ohne Yield: {0} ms", sw.ElapsedMilliseconds);
          sw.Reset();
          sw.Start();
          c.ArbeitMitYield();
          Console.WriteLine("Arbeit mit Yield: {0} ms", sw.ElapsedMilliseconds);
          Console.ReadKey();
        }
      }
    
      class C1
      {
    
        internal void ArbeitOhneYield()
        {
          int i = 0;
          foreach (var item in ColOhneYield())
          {
            i++;
            if (i > 10) return;
          }
        } 
    
        internal void ArbeitMitYield()
        {
          int i = 0;
          foreach (var item in ColMitYield())
          {
            i++;
            if (i > 10) return;
          }
        }
    
        internal List<int> ColOhneYield()
        {
        List<int> l = new List<int>();
        for (int i = 0; i < 100; i++)
    			{
    			 l.Add(DoWork(i));
    			}
        return l;
        }
    
        internal IEnumerable ColMitYield()
        {
          for (int i = 0; i < 100; i++)
          {
            yield return DoWork(i);
          }
        }
    
        internal int DoWork(int i)
        {
          Thread.Sleep(100);
          return i;
        }
      }
    
    }
    

    --
    Viele Gruesse
    Peter

    • Als Antwort markiert O. Stippe Mittwoch, 9. Mai 2012 05:58
    Dienstag, 8. Mai 2012 06:41

Alle Antworten

  • Das Benutzen einer Suchmaschine führt zu: http://unity3d.com/unity/

    Der Code selbst sieht nach einer State Machine aus, welch mittels Iteratoren angesprochen wird.

    Freitag, 4. Mai 2012 11:38
  • Das Benutzen einer Suchmaschine führt zu: http://unity3d.com/unity/

    Hallo Stefan,

    zu Punkt oben --- OK.

                         -- Kennst Du die Library? Zu empfehlen?

    Ich kann diese Funktion mehrfach anrufen, es wird jeder Wert dann zurückgegeben.

    Wo ist da der Vorteil?

     private string[] strings;
              private int ctr = 0;
              // Enumerable classes can return an enumerator
              public IEnumerator<string> GetEnumerator()
              {
                  foreach (string s in strings)
                  {
                      yield return s;
                  }
              }
     
    Grüße Oliver

    Sonntag, 6. Mai 2012 18:07
  • Ne, die Bibliothek kenne ich nicht.

    Ob die Nutzung von yield einen Vorteil bietet oder nicht, ist definitiv nicht mit diesem Quellcodefragment zu beantworten.

    Montag, 7. Mai 2012 06:54
  • Ne, die Bibliothek kenne ich nicht.

    Ob die Nutzung von yield einen Vorteil bietet oder nicht, ist definitiv nicht mit diesem Quellcodefragment zu beantworten.

    Hallo,

    sorry eine Frage noch.

    Könnte man es anders beantworten? Veranschaulichen, wo der große Vorteil von yield ist?

    Grüße Oliver


    • Bearbeitet O. Stippe Montag, 7. Mai 2012 10:15 Format
    Montag, 7. Mai 2012 10:14
  • yield bietet den Vorteil, auf die Bereitstellung von Gesamtmengen für Iterationen verzichten zu können. Mit yield kann man ein Enumerator-Objekt “aufbrechen”, so dass immer nur das aktuell benötigte Element bereitgestellt werden braucht.
     
    --
    Viele Gruesse
    Peter
    Montag, 7. Mai 2012 10:36
  • Hallo Peter,

    und bei jedem Aufruf wird eben auf das nächste Element geschaltet. Sehe ich es richtig?

    Grüße Oliver

    Dienstag, 8. Mai 2012 04:42
  • Bei jedem Next des Enumerators wird mit Current das aktuelle Element geholt. Bei der Nutzung von yield wird erst in diesem Moment das Element wirklich bereitgestellt.
     
    Zum weiteren Verständnis kannst Du Dir mal die Zeitmessung in der folgenden Demo anschauen:
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Collections;
    using System.Threading;
    
    namespace ConsoleApplication1
    {
      class Program
      {
        static void Main(string[] args)
        {
          C1 c = new C1();
          Stopwatch sw = new Stopwatch();
          sw.Start();
          c.ArbeitOhneYield();
          Console.WriteLine("Arbeit ohne Yield: {0} ms", sw.ElapsedMilliseconds);
          sw.Reset();
          sw.Start();
          c.ArbeitMitYield();
          Console.WriteLine("Arbeit mit Yield: {0} ms", sw.ElapsedMilliseconds);
          Console.ReadKey();
        }
      }
    
      class C1
      {
    
        internal void ArbeitOhneYield()
        {
          int i = 0;
          foreach (var item in ColOhneYield())
          {
            i++;
            if (i > 10) return;
          }
        } 
    
        internal void ArbeitMitYield()
        {
          int i = 0;
          foreach (var item in ColMitYield())
          {
            i++;
            if (i > 10) return;
          }
        }
    
        internal List<int> ColOhneYield()
        {
        List<int> l = new List<int>();
        for (int i = 0; i < 100; i++)
    			{
    			 l.Add(DoWork(i));
    			}
        return l;
        }
    
        internal IEnumerable ColMitYield()
        {
          for (int i = 0; i < 100; i++)
          {
            yield return DoWork(i);
          }
        }
    
        internal int DoWork(int i)
        {
          Thread.Sleep(100);
          return i;
        }
      }
    
    }
    

    --
    Viele Gruesse
    Peter

    • Als Antwort markiert O. Stippe Mittwoch, 9. Mai 2012 05:58
    Dienstag, 8. Mai 2012 06:41