/// <summary>
        /// Sends a message to the game coordinator as a job, waits for the job to complete, and returns the response message
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        protected internal async Task <GameCoordinatorMessage> SendJobAsync(GameCoordinatorMessage message)
        {
            (var task, var job) = _jobs.AddJob();

            await SendAsync(message.WithJobId(job)).ConfigureAwait(false);

            return(await task.ConfigureAwait(false));
        }
        /// <summary>
        /// Sends a message to the game coordinator as a job, waits for the job to complete, and returns the response body as an async task
        /// </summary>
        /// <returns></returns>
        protected internal async Task <T> SendJobAsync <T>(GameCoordinatorMessage message)
        {
            if (typeof(T) == typeof(GameCoordinatorMessage))
            {
                return((T)(object) await SendJobAsync(message).ConfigureAwait(false)); // ok c#
            }
            GameCoordinatorMessage response = await SendJobAsync(message).ConfigureAwait(false);

            return(response.Deserialize <T>());
        }
 internal async Task DispatchToReceiver(GameCoordinatorMessage message)
 {
     if (_dispatchers.TryGetValue(message.MessageType, out var value))
     {
         foreach (GameCoordinatorReceiver dispatch in value.GetInvocationList())
         {
             try
             {
                 await dispatch(message).ConfigureAwait(false);
             }
             catch (Exception e)
             {
                 await _log.ErrorAsync($"A game coordinator message receiver threw an exception: {e}").ConfigureAwait(false);
             }
         }
     }
     else
     {
         await _log.VerboseAsync($"Received unknown game coordinator message of type {message.MessageType} ({(int)message.MessageType})").ConfigureAwait(false);
     }
 }
 protected async Task <GameCoordinatorMessage> SendJobAsync(GameCoordinatorMessage message)
 {
     return(await Client.SendJobAsync(message).ConfigureAwait(false));
 }
 /// <summary>
 /// Sends a message using to Steam on the <see cref="SteamNetworkClient"/>
 /// </summary>
 /// <param name="message">The message to send</param>
 /// <returns>An awaitable task</returns>
 protected async Task SendAsync(GameCoordinatorMessage message)
 {
     await Client.SendAsync(message).ConfigureAwait(false);
 }
 /// <summary>
 /// Sends a message to the game coordinator as an async task
 /// </summary>
 /// <returns></returns>
 protected internal async Task SendAsync(GameCoordinatorMessage message)
 {
     await SendAsync(message.MessageType, message.Protobuf, message.Serialize()).ConfigureAwait(false);
 }
 private static Task InvokeGCBodyAsync <T>(GameCoordinatorMessage message, Delegate d)
 {
     return((d as Func <T, Task>)(message.Deserialize <T>()));
 }