Hi,

I have a question about the threadpool. ThreadPool accepts to pass along an object as shown in my code.

I will pass along 3 doubles, which I ofcourse could make to a string object, - and then convert it back to doubles in the "receiveDoubles" function. This is no problem to do.

However, I wonder if it is possible to pass along the doubles as type "double" and receive those 3 doubles as type "double" in the "receiveDoubles" function, which mean that no conversion will be needed anywhere?
(Reason is otherwise a huge amount of conversions)

        public void receiveDoubles(object getdoubles)
        {
            //Is it possible to receive doubles without converting here, which takes time?
            double one = 0;
            double two = 0;
            double three = 0;
        }
        private void button1_Click(object sender, EventArgs e)
        {

            object senddoubles = new object();

            //Send along those doubles
            double one = 21.51;
            double two = 21.52;
            double three = 21.53;

            ThreadPool.QueueUserWorkItem(new WaitCallback(receiveDoubles), senddoubles);
        }

Dani AI

Generated

Short answer: you can't change the ThreadPool API — the state parameter is object — so you must pass some object. That said, you don't need to convert doubles to strings and parse them back. 's idea (a grouped type) is correct, but note an important detail: if you use a value type (a struct or a raw double) it will be boxed when passed as object (an allocation + copy). For best results either use a small reference type or modern task-based APIs so the values are passed without expensive string conversions.

Common, practical options (none require converting to/from string):

  • Use a tiny immutable class (no boxing).
  • Use a double[] (reference type).
  • Use Tuple<double,double,double> or a custom class.
  • Use Task.Run (closure captures the doubles directly).

Example: small wrapper class + ThreadPool

class DoubleBox {
    public readonly double A, B, C;
    public DoubleBox(double a, double b, double c) { A = a; B = b; C = c; }
}

var state = new DoubleBox(21.51, 21.52, 21.53);
ThreadPool.QueueUserWorkItem(s =>
{
    var box = (DoubleBox)s;
    // use box.A, box.B, box.C
}, state);

Example: preferred modern style (no object state at all)

double a = 21.51, b = 21.52, c = 21.53;
Task.Run(() => ProcessDoubles(a, b, c));

void ProcessDoubles(double x, double y, double z) { /* work on doubles */ }

Notes and troubleshooting tips:

  • If throughput is critical, avoid repeated allocations: consider pooling (e.g., reusing arrays) or ArrayPool<T> to reduce GC churn.
  • Make state immutable or copy it before enqueuing — mutable shared objects cause races.
  • Measure before optimizing: boxing a small struct is usually cheaper than parsing strings, but a lot depends on frequency — profile to decide.

In short: avoid string conversions; prefer a reference holder (class/array/Tuple) or Task-based capture for clarity and minimal overhead. 's approach is fine, but prefer a class or Task-based pattern to avoid boxing and extra copies.

Recommended Answers

All 2 Replies

Yes, create a structure to hold your doubles;

public struct MyDoubles {
    public double one;
    public double two;
    public double three;

    publid MyDoubles(double o, double t, double h) {
        one = o;
        two = t;
        three = h;
    }
}

Then you'd call your method

MyDoubles senddoubles = new MyDoubles(one, two, three);

ThreadPool.QueueUserWorkItem(new WaitCallback(receiveDoubles), senddoubles);

And in your receiveDoubles you'd convert it back to the structure

 public void receiveDoubles(object getdoubles) {
     MyDoubles sentDoubles = (MyDoubles) getdoubles;

     ...

Thanks Momerath,

That seems to be a good solution!

Regards

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.