Is ThreadPool QueueUserWorkItem best option for handling event?
Without seeing the rest of your code it's hard to know what's going on but this is always* bad:

string data = GetByteData(characteristic.Service.Device.BluetoothAddress).Result;


* as long as GetByteData is async and returning a Task&lt;string&gt;

You should queue an async delegate instead:

ThreadPool.QueueUserWorkItem(async x =&gt;
    {
        GattCharacteristic characteristic = sender;
        string data = await GetByteData(characteristic.Service.Device.BluetoothAddress).ConfigureAwait(false);
        queue.Enqueue(new EventDataModel { IOData = characteristic, IOKey = characteristic.Service.Device.BluetoothAddress.ToString() });
    });


Note the use of await with ConfigureAwait(false). See Stephen Cleary's blog to learn more about why blocking on async code is such a bad idea.