как использовать QueueUserWorkItem с состоянием ref / out?

2

Можно ли сделать:

ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), ref data);

чтобы мой ThreadProc мог сделать данные вызывающего абонента в другом месте, чем при возникновении вызова?

Если это невозможно, существует ли способ реализовать такую ​​функциональность с помощью IntPtr или что-то в этом роде?

Теги:
multithreading

5 ответов

2

Вот вы, полный рабочий пример:

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 вы играете с большим огнем. Когда это становится сложно, вы начинаете рисковать тупиками и всякими гадости.

  • 0
    @ sam..i я не хотел публиковать примеры кода, потому что это ОЧЕНЬ ОЧЕНЬ опасно. Я не думаю, что смог бы спать по ночам, если бы где-нибудь нашел этот код :) .. но +1 за полный пример
1

Нет, просто потому, что определение WaitCallback(object state) содержит параметр non-ref.

И если бы вы могли, это было бы по сути не-потокобезопасным.

  • 0
    ..хахаха, я просто добавил то же самое в свой ответ ..
1

Нет, QueueUserWorkItem не поддерживает эту подпись, кроме того, это будет кошмар для отладки в многопоточном приложении.

1

Нет, и было бы нецелесообразно пытаться реализовать свою функциональность самостоятельно. Определение потока означает, что вы не знаете, когда оно изменит значение data. Передача чего-либо по ссылке на нить практически гарантировала бы какое-то состояние гонки или нарушение concurrency.

0

Это так просто. Используйте объект класса как объект состояния. Фактически ссылка на объект класса будет передана путем создания потока, и поэтому у вас будут общедоступные свойства класса как взаимные переменные между создателем потока и созданным потоком.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню