5

ThreadPool.QueueUserWorkItem (WaitCallback, Object)ターゲットメソッドとデータでスレッドを開始するために使用します。メソッドに複数のデータを渡すことはできますか? の 2 番目のパラメーターはQueueUserWorkItem (WaitCallback, Object)配列にすることができますか?

4

7 に答える 7

4

2番目のパラメーターは配列にすることができますが、データを含めるためのカスタムクラスを作成することをお勧めします。このようにして、渡すデータは完全に入力されます。

于 2010-02-19T15:03:27.793 に答える
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

強く型付けされたプラマーターを取得できるように、クラスを使用する例を次に示します。

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 に答える
3

はい、引数の型は System.Object であるため、何でも渡すことができます。http://msdn.microsoft.com/en-us/library/4yd16hza.aspx

于 2010-02-19T15:01:29.917 に答える
1

最も便利な方法は、ラムダ式を使用することです。

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

これは、このAPIを使用するための最も適切な方法です。

C#コンパイラは内部でクラスを生成します。このメソッドは、クラスを明示的に使用するのと(実質的に)同じくらい高速です。

于 2012-01-27T16:29:01.793 に答える
1

.NET のすべての型はオブジェクトから派生するため、必要なものを QueueUserWorkItem に渡すことができます。WaitCallback メソッドでキャストするだけです。

于 2010-02-19T15:02:00.293 に答える
0

実際、ラムダ式を使用するのが最も簡単な方法です。

ただし、 ThreadPool.QueueUserWorkItem の状態引数を使用して引数を渡さないことは、アンチパターンと見なす必要があります。

私のアプリでは、以下が一貫して機能します。

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 に答える