<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.8.15">
  <compounddef id="md__docs_learn" kind="page">
    <compoundname>md_Docs_learn</compoundname>
    <title>Learn</title>
    <briefdescription>
    </briefdescription>
    <detaileddescription>
<para><heading level="2">Task Parallel Library </heading>
</para>
<para>If you are new to the Task Parallel Library, please see this overview by Sacha Barber on <ulink url="http://www.codeproject.com/Articles/152765/Task-Parallel-Library-1-of-n">Code Project</ulink> or the reference documentation on <ulink url="http://msdn.microsoft.com/en-us/library/dd537609(v=vs.100).aspx">MSDN</ulink>.</para>
<para><heading level="2">API Reference </heading>
</para>
<para>The <ulink url="http://spicypixel.com/developer/concurrency-kit/api-reference/">Concurrency Kit API Reference</ulink> is a good place to start if you want to see what is in the library and learn more about how fibers and coroutines are supported.</para>
<para><heading level="2">Tasks vs. Unity Coroutines </heading>
</para>
<para>Unity has <ulink url="http://unity3d.com/support/documentation/ScriptReference/index.Coroutines_26_Yield.html">built-in support</ulink> for coroutines and so you may be wondering how tasks are different. This section calls out a few key distinctions.</para>
<para><heading level="3">Declaration and Execution</heading>
</para>
<para>Starting a coroutine in Unity requires one to define an explicit method for the routine and then initiate it with <ulink url="http://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.StartCoroutine.html">MonoBehaviour.StartCoroutine</ulink>.</para>
<para><programlisting filename=".cs"><codeline><highlight class="keyword">using</highlight><highlight class="normal"><sp/>UnityEngine;</highlight></codeline>
<codeline><highlight class="normal"></highlight><highlight class="keyword">using</highlight><highlight class="normal"><sp/><ref refid="namespace_system" kindref="compound">System</ref>.<ref refid="namespace_system_1_1_collections" kindref="compound">Collections</ref>;</highlight></codeline>
<codeline><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal"></highlight><highlight class="keyword">public</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">class<sp/></highlight><highlight class="normal">example<sp/>:<sp/>MonoBehaviour<sp/>{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>Start()<sp/>{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>print(</highlight><highlight class="stringliteral">&quot;Starting<sp/>&quot;</highlight><highlight class="normal"><sp/>+<sp/>Time.time);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>StartCoroutine(WaitAndPrint(2.0F));</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>print(</highlight><highlight class="stringliteral">&quot;Before<sp/>WaitAndPrint<sp/>Finishes<sp/>&quot;</highlight><highlight class="normal"><sp/>+<sp/>Time.time);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>}</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>IEnumerator<sp/>WaitAndPrint(</highlight><highlight class="keywordtype">float</highlight><highlight class="normal"><sp/>waitTime)<sp/>{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>yield<sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">new</highlight><highlight class="normal"><sp/>WaitForSeconds(waitTime);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>print(</highlight><highlight class="stringliteral">&quot;WaitAndPrint<sp/>&quot;</highlight><highlight class="normal"><sp/>+<sp/>Time.time);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>}</highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
</programlisting></para>
<para>Note how the WaitAndPrint method requires the special IEnumerator return type, the signature of all coroutines. Using tasks, the same example could be written as follows.</para>
<para><programlisting filename=".cs"><codeline><highlight class="keyword">using</highlight><highlight class="normal"><sp/>UnityEngine;</highlight></codeline>
<codeline><highlight class="normal"></highlight><highlight class="keyword">using</highlight><highlight class="normal"><sp/><ref refid="namespace_system" kindref="compound">System</ref>.<ref refid="namespace_system_1_1_collections" kindref="compound">Collections</ref>;</highlight></codeline>
<codeline><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal"></highlight><highlight class="keyword">public</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">class<sp/></highlight><highlight class="normal">example<sp/>:<sp/>ConcurrentBehaviour<sp/>{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>Start()<sp/>{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>print(</highlight><highlight class="stringliteral">&quot;Starting<sp/>&quot;</highlight><highlight class="normal"><sp/>+<sp/>Time.time);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>taskFactory.StartNew(WaitAndPrint(2.0F));</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>print(</highlight><highlight class="stringliteral">&quot;Before<sp/>WaitAndPrint<sp/>Finishes<sp/>&quot;</highlight><highlight class="normal"><sp/>+<sp/>Time.time);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>}</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>IEnumerator<sp/>WaitAndPrint(</highlight><highlight class="keywordtype">float</highlight><highlight class="normal"><sp/>waitTime)<sp/>{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>yield<sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">new</highlight><highlight class="normal"><sp/>WaitForSeconds(waitTime);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>print(</highlight><highlight class="stringliteral">&quot;WaitAndPrint<sp/>&quot;</highlight><highlight class="normal"><sp/>+<sp/>Time.time);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>}</highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
</programlisting></para>
<para>As you can see, only a minimal change is required to use an existing coroutine as a task with the Concurrency Kit. But, these are some of the benefits you get when doing so. Because the TaskFactory.StartNew method returns a Task you can:</para>
<para><itemizedlist>
<listitem><para>Wait from any other thread for the task to complete using <ulink url="http://msdn.microsoft.com/en-us/library/dd235635.aspx">Task.Wait</ulink></para>
</listitem><listitem><para>Continue execution based on multiple tasks using <ulink url="http://msdn.microsoft.com/en-us/library/dd270672">Task.WaitAny</ulink> or <ulink url="http://msdn.microsoft.com/en-us/library/dd270695">Task.WaitAll</ulink></para>
</listitem><listitem><para>Check both the <ulink url="http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskstatus.aspx">completion status</ulink> and the <ulink url="http://msdn.microsoft.com/en-us/library/dd321405">result</ulink> of a task</para>
</listitem></itemizedlist>
</para>
<para>Additionally, you can pass in a <ulink url="http://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken.aspx">CancellationToken</ulink> in order to cancel a specific instance of an executing task or a group of executing tasks. Unity only supports stopping all instances of a coroutine using <ulink url="http://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.StopCoroutine.html">MonoBehaviour.StopCoroutine</ulink> or <ulink url="http://unity3d.com/support/documentation/ScriptReference/MonoBehaviour.StopAllCoroutines.html">MonoBehaviour.StopAllCoroutines</ulink> which in some circumstances isn&apos;t fine grained enough.</para>
<para><heading level="3">Anonymous Methods</heading>
</para>
<para>Sometimes it is more convenient to write a workflow using anonymous methods instead of declaring a coroutine, especially for simple property changes. Here is the same example rewritten to use an anonymous method instead of an explicitly declared one.</para>
<para><programlisting filename=".cs"><codeline><highlight class="keyword">using</highlight><highlight class="normal"><sp/>UnityEngine;</highlight></codeline>
<codeline><highlight class="normal"></highlight><highlight class="keyword">using</highlight><highlight class="normal"><sp/><ref refid="namespace_system" kindref="compound">System</ref>.<ref refid="namespace_system_1_1_collections" kindref="compound">Collections</ref>;</highlight></codeline>
<codeline><highlight class="normal"></highlight></codeline>
<codeline><highlight class="normal"></highlight><highlight class="keyword">public</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">class<sp/></highlight><highlight class="normal">example<sp/>:<sp/>ConcurrentBehaviour<sp/>{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>Start()<sp/>{</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>print(</highlight><highlight class="stringliteral">&quot;Starting<sp/>&quot;</highlight><highlight class="normal"><sp/>+<sp/>Time.time);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>taskFactory.StartNew(</highlight><highlight class="keyword">new</highlight><highlight class="normal"><sp/>YieldForSeconds(2.0F)).</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>ContinueWith(lastTask<sp/>=&gt;<sp/>print(</highlight><highlight class="stringliteral">&quot;WaitAndPrint<sp/>&quot;</highlight><highlight class="normal"><sp/>+<sp/>Time.time),</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>taskScheduler);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>print(</highlight><highlight class="stringliteral">&quot;Before<sp/>WaitAndPrint<sp/>Finishes<sp/>&quot;</highlight><highlight class="normal"><sp/>+<sp/>Time.time);</highlight></codeline>
<codeline><highlight class="normal"><sp/><sp/><sp/><sp/>}</highlight></codeline>
<codeline><highlight class="normal">}</highlight></codeline>
</programlisting></para>
<para>Tasks also allow invocation of standard methods and functions that don&apos;t have an <bold>IEnumerator</bold> return type such as the <bold>print</bold> method above.</para>
<para><heading level="3">Portability</heading>
</para>
<para>Unity coroutines allow one to write asynchronous code, but that code is not portable outside of the Unity framework because of the dependency on the Unity coroutine scheduler. If you are writing or using a library that needs to operate in a Unity environment but also in an external environment such as for tools, framework, or cross-platform development, the Task Parallel Library is the standard way to expose asynchronous behavior in your public interface.</para>
<para><heading level="2">Advanced Uses </heading>
</para>
<para>Tasks make it easy to run functions on another thread and to run logic in parallel. Here are some of the more advanced things you can do with them:</para>
<para><itemizedlist>
<listitem><para><bold>AI:</bold> Perform path or planning searches in parallel and select either the first to complete or the best from multiple options when all searches complete</para>
</listitem><listitem><para><bold>AI:</bold> Run high-level agent behaviors across multiple threads and optionally at a different frequency than the Unity run loop for more control over scalability</para>
</listitem><listitem><para><bold>Physics: </bold> Calculate multiple ballistic trajectories to zero in on a solution</para>
</listitem><listitem><para><bold>Networking:</bold> Stream multiple assets in parallel from a remote site</para>
</listitem><listitem><para><bold>Networking:</bold> Asynchronously coordinate a complex sequence of events such as NAT type discovery, matchmaking on a master server, connection management, fallbacks, and timeout handling</para>
</listitem></itemizedlist>
</para>
<para>One caveat to working with multiple threads and Unity is that much like working with a UI framework, all access to Unity objects must be made from the main Unity thread. This makes it necessary to adopt a multi-threaded architecture like a producer / consumer model in order to safely run operations in parallel and access or marshal game state across threads. </para>
    </detaileddescription>
  </compounddef>
</doxygen>
