SmartThreadPool - возможно ли передать метод делегата с параметрами метода? - PullRequest
0 голосов
/ 13 октября 2011

У меня есть длительный процесс под названием ImportProductInformation, вызываемый консольным приложением, которое я пытаюсь ускорить, что является отличным кандидатом на пул потоков, поэтому я немного поискал и наткнулся на SmartThreadPool на CodeProject и пытаюсь его реализовать.

ImportProductInformation в настоящее время требуется «элемент», который представляет собой просто одну строку структуры объекта, извлеченную из списка. SmartThreadPool использует делегат с именем "WorkItemCallback", но если я создаю его, как показано ниже, он жалуется на "Ожидаемое имя метода" в цикле foreach на smartThreadPool.QueueWorkItem, так как кажется, что я не могу передать свои параметры делегированному методу. Что мне здесь не хватает? Я уверен, что это что-то глупое ... нубу не хватает опыта работы с делегатами ... любая помощь будет признательна:

    public static void ImportProductInformation_Exec()
    {
        // List
        List<productinformation> _list = GetProductInformation();

        // Import
        if (_list != null)
        {
            SmartThreadPool smartThreadPool = new SmartThreadPool();

            foreach (var item in _list)
            {
                smartThreadPool.QueueWorkItem
                  (new WorkItemCallback
                    (ImportProductInformation(item)));
            }

            smartThreadPool.WaitForIdle();
            smartThreadPool.Shutdown();
        }
    }

    public void ImportProductInformation(productinformation item)
    {
        // Do work associated with "item" here
    }

Если я изменяю цикл на это, я получаю «Метод используется как Тип» в ошибке сборки:

            foreach (var item in _list)
            {
                ImportProductInformation ipi = 
                  new ImportProductInformation(item);

                smartThreadPool.QueueWorkItem(new WorkItemCallback(ipi));
            }

Закончилась работа с этим:

public class ProductInformationTaskInfo
{
    public productinformation ProductInformation;

    public ProductInformationTaskInfo(productinformation pi)
    {
        ProductInformation = pi;
    }
}

public class PI
{
    foreach (var item in _list)
    {
        ProductInformationTaskInfo pi = 
          new ProductInformationTaskInfo(item);
        smartThreadPool.QueueWorkItem
          (new WorkItemCallback
            (ImportProductInformation), pi);
    }

    public static object ImportProductInformation(Object _pi)
    {
        ProductInformationTaskInfo pi = (ProductInformationTaskInfo)_pi;
        var item = pi.ProductInformation;

        // Do work here
    }
}

Ответы [ 2 ]

1 голос
/ 13 октября 2011

Вы можете использовать анонимные методы:

int a = 15;
String b = "hello world!";
ThreadPool.QueueUserWorkItem((state)=>SomeFunction(a,b));
1 голос
/ 13 октября 2011

Я не знаю или у меня есть SmartThreadPool, следующее приблизительное:

foreach (var item in _list)
{
   var itemCopy = item;
   smartThreadPool.QueueWorkItem
              (dummy => ImportProductInformation(itemCopy));
}

Возможно, вам придется сделать некоторые исправления.
Это работает, потому что лямбда захватывает переменную из содержащего метода,И именно поэтому вам нужна itemCopy.

Но обратите внимание, что обычный ThreadPool не подходит для задач длительного выполнения, то же самое может иметь место для SmartThreadPool.Следует также ограничить количество потоков, и когда ImportProductInformation выполняет в основном потоки ввода-вывода, это может вообще не помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...