Search Unity

Using System.Threading.Thread and Windows Phone 8.1

Discussion in 'Windows' started by PixelSquad, Feb 6, 2018.

  1. PixelSquad

    PixelSquad

    Joined:
    Sep 4, 2014
    Posts:
    111
    Hi guys

    Just a few nice things related to threads that pop up when I try and build a game on WP8.1 with Unity 5.6. Namely:

    1. What's the equivalent of System.Threading.Thread on WP8.1? (as the notorious "error CS0234: The type or namespace name 'Thread' does not exist in the namespace 'System.Threading'" pops up..)

    2. What's the equivalent of Thread.Sleep()?

    3. How do I know if the current thread is the Unity main thread? Before that, I used to use System.Threading.Thread.CurrentThread, but that's obviously no longer available.

    Sometimes I wish the people who created this API just left the basic classes untouched. But there must be a good reason for it, and that's the way things are...

    Many thanks for any replies
     
  2. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    6,452
    https://docs.microsoft.com/en-us/uwp/api/windows.system.threading.threadpool

    System.Threading.Tasks.Task.Delay, but that doesn't exactly do what you want (it's an async call). Another trick is to create a ManualResetEvent that never gets set and wait on it with a timeout.

    Use this.

    Eh, I doubt it, given the fact they readded those classes.
     
  3. PixelSquad

    PixelSquad

    Joined:
    Sep 4, 2014
    Posts:
    111
    Thanks Tautvydas, you're a star!

    Ar tu lietuvis? Aš išmoktu truputi lietuviški nes turiu ypatingas draugas iš lietuva. Anyway...

    Digging deeper into it, I found that they exterminated the Socket class in this version too. Have you got any pointers for that or shall I go on a quest to write a wrapper?

    So they were making everyone waste a massive amount of time in the end... Pretty.
     
  4. PixelSquad

    PixelSquad

    Joined:
    Sep 4, 2014
    Posts:
    111
    Hi again Tautvydas,

    Looks like UnityEngine.WSA.Application.RunningOnAppThread() returns true even if the code is not running on the main thread... You can find a screenshot attached.

    Note this is the editor. Am I doing the right thing?

    Many thanks
     

    Attached Files:

  5. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    6,452
    Yes.

    Sockets are problematic. They have some in Windows.Networking namespace, and they also have WinSock2 available from C++. Neither is easy to use with cross platform Unity code.

    Pretty much

    Looking at the implementation, it seems it's hardcoded to always return true in the editor. It should work in the build, though.. you could use whatever you used in the editor before guarded with #if UNITY_EDITOR.
     
  6. PixelSquad

    PixelSquad

    Joined:
    Sep 4, 2014
    Posts:
    111
    Gerai! Ačiu labai mano draugas.

    I had a really joyful time creating a StreamSocket / Socket wrapper for my project. They reinvented the wheel, but made it square this time. Why not! If I had done it, I would actually have improved it by removing exceptions...

    I imagine someone in the position I was yesterday would find this code useful even if as just a starting point. If you use this, give me a shout in this thread to say it helped, I'll be glad it did.

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using System.Net.Sockets;
    6. using System.Net;
    7. using System;
    8.  
    9. #if UNITY_5_6 && NETFX_CORE
    10. using Windows.Networking.Sockets;
    11. using System.IO;
    12. using System.Threading.Tasks;
    13. using Windows.Storage.Streams;
    14. using Windows.Foundation;
    15. #endif
    16.  
    17. public class SocketWrapper
    18. {
    19. #if UNITY_5_6 && NETFX_CORE
    20.     StreamSocket socket = null;
    21.     DataWriter writer = null;
    22.     DataReader reader = null;
    23.     DataReaderLoadOperation readOperation = null;
    24.  
    25.     public bool Connect(string serverAddress, int serverPort)
    26.     {
    27.         try
    28.         {
    29.             socket = new Windows.Networking.Sockets.StreamSocket();
    30.             var hostName = new Windows.Networking.HostName(serverAddress);
    31.  
    32.             WindowsRuntimeSystemExtensions.AsTask(socket.ConnectAsync(hostName, serverPort.ToString())).Wait();
    33.  
    34.             writer = new DataWriter(socket.OutputStream);
    35.             reader = new DataReader(socket.InputStream);
    36.             reader.InputStreamOptions = InputStreamOptions.Partial;
    37.  
    38.             return true;
    39.         }
    40.         catch (Exception ex)
    41.         {
    42.             Debug.LogError(ex.ToString());
    43.             return false;
    44.         }
    45.     }
    46.  
    47.     public bool Close()
    48.     {
    49.         try
    50.         {
    51.             if (readOperation  != null)
    52.             {
    53.                 if (readOperation.Status == AsyncStatus.Started)
    54.                 {
    55.                     try
    56.                     {
    57.                         readOperation.Cancel();
    58.                     }
    59.                     catch (Exception ex)
    60.                     {
    61.                         Debug.LogError("Error cancelling read operation: " + ex.ToString());
    62.                     }
    63.                 }
    64.                 readOperation = null;
    65.             }
    66.  
    67.             if (reader != null)
    68.             {
    69.                 reader.Dispose();
    70.                 reader= null;
    71.             }
    72.  
    73.             if (writer != null)
    74.             {
    75.                 writer.Dispose();
    76.                 writer = null;
    77.             }
    78.  
    79.             if (socket != null)
    80.             {
    81.                 socket.Dispose();
    82.                 socket = null;
    83.             }
    84.             return true;
    85.         }
    86.         catch (Exception ex)
    87.         {
    88.             Debug.LogError("SocketWrapper exception: " + ex.ToString());
    89.             return false;
    90.         }
    91.     }
    92.  
    93.     public bool Send(byte[] data)
    94.     {
    95.         if (writer == null)
    96.         {
    97.             Debug.LogError("writer is null - not connected?");
    98.             return false;
    99.         }
    100.      
    101.         try
    102.         {
    103.             writer.WriteBytes(data);
    104.             writer.StoreAsync();
    105.             return true;
    106.         }
    107.         catch (Exception ex)
    108.         {
    109.             Debug.LogError("SocketWrapper.Send - Exception: " + ex.ToString());
    110.             return false;
    111.         }
    112.     }
    113.  
    114.     public bool ReadAnyAvailableData()
    115.     {
    116.         if (readOperation != null && readOperation.Status == AsyncStatus.Error)
    117.         {
    118.             Debug.LogError("readOperation resulted in an error.");
    119.             return false;
    120.         }
    121.      
    122.         if (readOperation == null || readOperation.Status == AsyncStatus.Completed)
    123.         {
    124.             // Eat more bytes to grow healthily
    125.             readOperation = reader.LoadAsync(1024); // 1024 happens to be the size of the buffer we use in Receive... why oh why...
    126.         }
    127.         return true;
    128.     }
    129.  
    130.     public int ReceivedByteCount()
    131.     {
    132.         return (int)reader.UnconsumedBufferLength;
    133.     }
    134.  
    135.     public int Receive(byte[] buffer)
    136.     {
    137.         int availableBytes = ReceivedByteCount();
    138.         if (availableBytes <= 0)
    139.         {
    140.             Debug.LogError("You shouldn't be here. Call AvailableBytes first!");
    141.             return -1;
    142.         }
    143.  
    144.         int readBytes = 0;
    145.         for (; readBytes < buffer.Length && reader.UnconsumedBufferLength > 0; ++readBytes)
    146.         {
    147.             buffer[readBytes] = reader.ReadByte();
    148.         }
    149.         return readBytes;
    150.     }
    151.  
    152. #else
    153.  
    154.     // Normal implementation
    155.     Socket socket = null;
    156.  
    157.     public bool Close()
    158.     {
    159.         try
    160.         {
    161.             socket.Shutdown(SocketShutdown.Both);
    162.             socket.Close();
    163.             return true;
    164.         }
    165.         catch (Exception ex)
    166.         {
    167.             Debug.LogError(ex.ToString());
    168.             return false;
    169.         }
    170.         finally
    171.         {
    172.             socket = null;
    173.         }
    174.     }
    175.  
    176.     public bool Connect(string serverAddress, int serverPort)
    177.     {
    178.         IPEndPoint serverEndpoint = GetServerEndPoint(serverAddress, serverPort);
    179.         if (serverEndpoint == null)
    180.         {
    181.             Debug.LogError("Failed resolving server address (DNS)");
    182.             return false;
    183.         }
    184.  
    185.         // Create socket, and connect
    186.         try
    187.         {
    188.             socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    189.             socket.Connect(serverEndpoint);
    190.  
    191.             return true;
    192.         }
    193.         catch (Exception e)
    194.         {
    195.             Debug.LogError("Error connecting to server: " + e.ToString());
    196.             return false;
    197.         }
    198.     }
    199.  
    200.     IPEndPoint GetServerEndPoint(string serverHostName, int serverPort)
    201.     {
    202.         try
    203.         {
    204.             IPAddress[] addresses = System.Net.Dns.GetHostAddresses(serverHostName);
    205.             if (addresses.Length == 0)
    206.             {
    207.                 Debug.LogError("Unable to retrieve address from specified host name: " + serverHostName);
    208.                 return null;
    209.             }
    210.  
    211.             // Found server address
    212.             return new IPEndPoint(addresses[0], serverPort);
    213.         }
    214.         catch (Exception ex)
    215.         {
    216.             Debug.LogError("Exception while determining server address: " + ex.ToString());
    217.             return null;
    218.         }
    219.     }
    220.  
    221.     public bool Send(byte[] data)
    222.     {
    223.         if (data == null)
    224.         {
    225.             Debug.LogError("SocketWrapper - data == null");
    226.             return false;
    227.         }
    228.  
    229.         try
    230.         {
    231.             socket.Send(data);
    232.             return true;
    233.         }
    234.         catch (Exception ex)
    235.         {
    236.             Debug.LogError("SocketWrapper.Send - Error sending data: " + ex.ToString());
    237.             return false;
    238.         }
    239.     }
    240.  
    241.     public int ReceivedByteCount()
    242.     {
    243.         try
    244.         {
    245.             if (socket == null)
    246.             {
    247.                 Debug.LogError("AvailableBytes - socket not initialised.");
    248.                 return -1;
    249.             }
    250.             return socket.Available;
    251.         }
    252.         catch (Exception ex)
    253.         {
    254.             Debug.LogError("SocketWrapper.AvailableBytes() - Error sending data: " + ex.ToString());
    255.             return -1;
    256.         }
    257.     }
    258.  
    259.     public int Receive(byte[] buffer)
    260.     {
    261.         if (buffer == null || buffer.Length <= 0)
    262.         {
    263.             Debug.LogError("SocketWrapper.Receive - buffer == null || buffer.Length <= 0");
    264.             return -1;
    265.         }
    266.  
    267.         try
    268.         {
    269.             return socket.Receive(buffer);
    270.         }
    271.         catch (Exception ex)
    272.         {
    273.             Debug.LogError("SocketWrapper.Receive - Exception: " + ex.ToString());
    274.             return -1;
    275.         }
    276.     }
    277.  
    278.     public bool ReadAnyAvailableData()
    279.     {
    280.         // Nothing to do here
    281.         return true;
    282.     }
    283. #endif
    284. }
    285.  
     
    Last edited: Feb 8, 2018
    Donghee02 likes this.
  7. Donghee02

    Donghee02

    Joined:
    Jul 5, 2017
    Posts:
    1
    Very Helpful.
    Thank you so much !