开发者

C# Can I pass more than one data into my target method when using ThreadPool?

use ThreadPool.QueueUse开发者_运维问答rWorkItem (WaitCallback, Object) to start a thread with my target method and data. Can I pass more than one data into my method? the second parameter in QueueUserWorkItem (WaitCallback, Object) can be an array?


The second parameter can be an array but you're better off creating a custom class for containing your data. That way the data you pass is fully typed.


Here is a example of using a class so you can get strongly typed pramaters

public class CreateUserTaskInfo
{
    public string username { get; };
    public string password { get; };
    public string sqlServer { get; };
    public string database { get; };
    public string practice { get; };
    public RemoteUserManager client { get; };
    public CreateUserTaskInfo(RemoteUserManager cli, string usr, string pass, string sql, string db, string prac)
    {
        client = cli;
        username = usr;
        password = pass;
        sqlServer = sql;
        database = db;
        practice = prac;
    }
}

public void ExampleFunction(...)
{
    //gather up the variables to be passed in
    var taskInfo = new CreateUserTaskInfo(remote, user, password, SqlInstancePath, AccountID, practiceName);

    //queue the background work and pass in the state object.
    ThreadPool.QueueUserWorkItem(new WaitCallback(RemoteUserManagerClient.CreateUser), taskInfo);
}

static public void CreateUser(object stateInfo)
{
    CreateUserTaskInfo ti = (CreateUserTaskInfo)stateInfo;

    //use ti in the method and access the properties, it will be 
    // the same object as taskInfo from the other method
}


Yes the type of the argument is System.Object so you can pass anything. http://msdn.microsoft.com/en-us/library/4yd16hza.aspx


Just cast your state object back, which also applies for ParameterizedThreadStart:

List<string> list = new List<string> {"1","2","3"};
ThreadPool.QueueUserWorkItem (CallBack, list);

void CallBack(object state)
{
    List<string> list = (List<string>) state;
}


All types in .NET derive from object so you can pass in anything you want to QueueUserWorkItem. Just cast it in your WaitCallback method.


The most convenient method is to use a lambda expression:

var localVariable = 42;
ThreadPool.QueueUserWorkItem (_ => { Console.WriteLine(localVariable); }, null);

This is the most sane way to use this API.

The C# compiler will generate a class internally. This method is (virtually) as fast as using a class explicitly.


Using a lambda expression is indeed the easiest way.

However, not using the state argument of the ThreadPool.QueueUserWorkItem to pass along arguments should be considered an anti-pattern:

The following consistently works in my app:

var parm = new ParallelInput()
                        {
                            threadIdNbr = threadId,
                            input = input,
                            inputLength = inputLen,
                            leftBlock = leftBlock,
                            leftBlockLength = leftBlockLength,
                            leftSiblingThreadData = leftSiblingThreadData,
                            rightSiblingThreadData = rightSiblingThreadData, 
                            threadCommon = threadCommon,
                            globalOutputWriter = globalOutputWriter,
                            threadWrittenAllCounter = threadWrittenAllCounter
                        };

ThreadPool.QueueUserWorkItem(pp => { var p = (ParallelInput)pp; rdr.parallelConvert(p.threadIdNbr, p.input, p.inputLength, p.leftBlock, p.leftBlockLength, p.leftSiblingThreadData, p.rightSiblingThreadData, p.threadCommon, p.globalOutputWriter, p.threadWrittenAllCounter); }, parm);

... and the following consistently fails on my hardware :

ThreadPool.QueueUserWorkItem(_ => rdr.parallelConvert(threadId, input, inputLen, leftBlock, leftBlockLength, leftSiblingThreadData, rightSiblingThreadData, threadCommon, globalOutputWriter, threadWrittenAllCounter), null);

... since it fails to provide all data within the input array. (Tested with VS2010 and .NET v4.0.30319)

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜