Repository: ccxt/ccxt
File: cs/ccxt/ws/Exchange.WsBridge.cs (C#)

Code before:
                }
            }
            return client;
        });
    }

    public async Task<object> watch(object url2, object messageHash2, object message = null, object subscribeHash2 = null, object subscription = null)
    {
        var url = url2.ToString();
        var messageHash = messageHash2.ToString();
        var subscribeHash = subscribeHash2?.ToString();
        var client = this.client(url);

        var future = (client.futures as ConcurrentDictionary<string, Future>).GetOrAdd(messageHash, (key) => client.future(messageHash));
        if (subscribeHash == null)
        {
            return await future;
        }
        var connected = client.connect(0);

        if ((client.subscriptions as ConcurrentDictionary<string, object>).TryAdd(subscribeHash, subscription ?? true))
        {
            await connected;
            if (message != null)
            {
                try
                {
                    await client.send(message);
                }
                catch (Exception ex)
                {
                    client.subscriptions.Remove(subscribeHash);
                    future.reject(ex);
                    // future.SetException(ex); check this out
                }

            }
        }
        return await future;
    }

    public async Task<object> watchMultiple(object url2, object messageHashes2, object message = null, object subscribeHashes2 = null, object subscription = null)
    {
        var url = url2.ToString();
        var messageHashes = (messageHashes2 as List<object>).Select(obj => obj.ToString()).ToList();
        var subscribeHashes = (subscribeHashes2 as List<object>).Select(obj => obj.ToString()).ToList();

        var client = this.client(url);

        var future = Future.race(messageHashes.Select(subHash => client.future(subHash)).ToArray());


Review comment (suggestion):
now `c#` counterpart for `watch` method follows the `ts` logic line by line in this area, plz check this: https://github.com/ccxt/ccxt/blob/master/ts/src/base/Exchange.ts#L1382

Code after:
            var keepAliveValue = this.safeInteger(wsOptions, "keepAlive", 30000) ?? 30000;
            var keepAlive = keepAliveValue;
            var decompressBinary = this.safeBool(this.options, "decompressBinary", true) as bool? ?? true;
            var client = new WebSocketClient(url, proxy, handleMessage, ping, onClose, onError, this.verbose, keepAlive, decompressBinary);

            var wsHeaders = this.safeValue(wsOptions, "headers", new Dictionary<string, object>() { });
            // iterate through headers
            if (wsHeaders != null)
            {
                var headers = wsHeaders as Dictionary<string, object>;
                foreach (var key in headers.Keys)
                {
                    client.webSocket.Options.SetRequestHeader(key, headers[key].ToString());
                }
            }
            return client;
        });
    }

    public async Task<object> watch(object url2, object messageHash2, object message = null, object subscribeHash2 = null, object subscription = null)
    {
        var url = url2.ToString();
        var messageHash = messageHash2.ToString();
        var subscribeHash = subscribeHash2?.ToString();
        var client = this.client(url);
        var backoffDelay = 0;

        Future existingFuture = null;
        if (subscribeHash == null && (client.futures as ConcurrentDictionary<string, Future>).TryGetValue(messageHash, out existingFuture))
        {
            return await existingFuture;
        }
        var future = client.future(messageHash);
        object clientSubscription = null;
        bool clientSubscriptionExists = (client.subscriptions as ConcurrentDictionary<string, object>).TryGetValue(subscribeHash, out clientSubscription);
        if (!clientSubscriptionExists)
        {
            (client.subscriptions as ConcurrentDictionary<string, object>).TryAdd(subscribeHash, subscription ?? true);
        }
        var connected = client.connect(backoffDelay);
        if (!clientSubscriptionExists)
        {
            await connected;
            if (message != null)
            {
                try
                {
                    await client.send(message);
                }
                catch (Exception ex)
                {