Можно ли сделать:
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), ref data);
чтобы мой ThreadProc мог сделать данные вызывающего абонента в другом месте, чем при возникновении вызова?
Если это невозможно, существует ли способ реализовать такую функциональность с помощью IntPtr или что-то в этом роде?
Вот вы, полный рабочий пример:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication19 {
class Program {
static object sync = new object();
static void Main(string[] args) {
int counter = 0;
ThreadPool.QueueUserWorkItem(new WaitCallback((_) => ThreadProc(ref counter)), null);
while (true) {
lock (sync) {
if (counter == 1) break;
}
Thread.Sleep(1);
}
Console.Write(counter);
Console.Read();
}
static void ThreadProc(ref int counter) {
lock (sync) {
counter++;
}
}
}
}
Примечание:
С точки зрения concurrency вы играете с большим огнем. Когда это становится сложно, вы начинаете рисковать тупиками и всякими гадости.
Нет, просто потому, что определение WaitCallback(object state)
содержит параметр non-ref.
И если бы вы могли, это было бы по сути не-потокобезопасным.
Нет, QueueUserWorkItem
не поддерживает эту подпись, кроме того, это будет кошмар для отладки в многопоточном приложении.
Нет, и было бы нецелесообразно пытаться реализовать свою функциональность самостоятельно. Определение потока означает, что вы не знаете, когда оно изменит значение data
. Передача чего-либо по ссылке на нить практически гарантировала бы какое-то состояние гонки или нарушение concurrency.
Это так просто. Используйте объект класса как объект состояния. Фактически ссылка на объект класса будет передана путем создания потока, и поэтому у вас будут общедоступные свойства класса как взаимные переменные между создателем потока и созданным потоком.