5

使用ThreadPool.QueueUserWorkItem (WaitCallback, Object)我的目标方法和数据启动一个线程。我可以将多个数据传递到我的方法中吗?第二个参数QueueUserWorkItem (WaitCallback, Object)可以是数组吗?

4

7 回答 7

4

第二个参数可以是一个数组,但您最好创建一个自定义类来包含您的数据。这样,您传递的数据是完全键入的。

于 2010-02-19T15:03:27.793 回答
3

是的,参数的类型是 System.Object 所以你可以传递任何东西。http://msdn.microsoft.com/en-us/library/4yd16hza.aspx

于 2010-02-19T15:01:29.917 回答
3

只需将您的状态对象转换回来,这也适用于ParameterizedThreadStart

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

void CallBack(object state)
{
    List<string> list = (List<string>) state;
}
于 2010-02-19T15:07:12.963 回答
3

这是使用类的示例,因此您可以获得强类型的 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
}
于 2010-02-19T15:12:45.480 回答
1

.NET 中的所有类型都派生自对象,因此您可以将任何您想要的内容传递给 QueueUserWorkItem。只需将其转换为您的 WaitCallback 方法即可。

于 2010-02-19T15:02:00.293 回答
1

最方便的方法是使用 lambda 表达式:

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

这是使用此 API 的最明智的方式。

C# 编译器将在内部生成一个类。此方法(实际上)与显式使用类一样快。

于 2012-01-27T16:29:01.793 回答
0

使用 lambda 表达式确实是最简单的方法。

但是,不使用 ThreadPool.QueueUserWorkItem 的 state 参数来传递参数应该被视为一种反模式:

以下内容始终适用于我的应用程序:

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);

...并且以下内容在我的硬件上始终失败:

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

...因为它无法提供输入数组中的所有数据。(使用 VS2010 和 .NET v4.0.30319 测试)

于 2016-06-28T09:58:21.410 回答