开发者

SmartThreadPool - Is it possible to pass delegate method with method parameters?

开发者 https://www.devze.com 2023-04-12 23:54 出处:网络
I have a long running process called ImportProductInformation called by a consoleapp that I\'m trying to speed up, which appears to be an excellent candidate for thread-pooling, so I did a little sear

I have a long running process called ImportProductInformation called by a consoleapp that I'm trying to speed up, which appears to be an excellent candidate for thread-pooling, so I did a little searching and came across SmartThreadPool on CodeProject and am trying to implement it.

ImportProductInformation currently requires an "item", which is just a single entity-framework row pulled from a list. SmartThreadPool uses a delegate called "WorkItemCallback", but if I build it like below it complains about "Method name expected" in the foreach loop on smartThreadPool.QueueWorkItem, as it appears I can't pass my params to the delegated method. What am I missing here? I'm sure it's something stupid...noob lacking experience with delegates...any help would be appreciated:

    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
    }

If I change the loop to this I get "Method is used like a Type" in the build error:

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

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

Ended up getting it to work with this:

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(Objec开发者_如何学Pythont _pi)
    {
        ProductInformationTaskInfo pi = (ProductInformationTaskInfo)_pi;
        var item = pi.ProductInformation;

        // Do work here
    }
}


I don't know or have the SmartThreadPool, the following is approximate:

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

You may have to do some fixing.
This works because the lambda captures a variable from the containing method. And that's why you need itemCopy.

But note that the normal ThreadPool is not suited for longrunning tasks, the same may hold for the SmartThreadPool. It should also keep a limit on the number of threads, and when ImportProductInformation does mainly I/O threading might not help at all.


You can use anonymous methods:

int a = 15;
String b = "hello world!";
ThreadPool.QueueUserWorkItem((state)=>SomeFunction(a,b));
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号