C # Can I pass some data to my target method when using ThreadPool?

use ThreadPool.QueueUserWorkItem (WaitCallback, Object) to start the thread with my target method and data. Can I pass some data to my method? the second parameter in QueueUserWorkItem (WaitCallback, Object) can be an array?

+4
source share
7 answers

Here is an example using the 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 } 
+3
source

The second parameter may be an array, but you better create your own class to hold your data. Thus, the data you transmit is completely printed.

+4
source

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

+3
source

Just throw your state object back, which also applies to ParameterizedThreadStart :

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

All types in .NET are inferred from the object, so you can pass everything you want into QueueUserWorkItem. Just add it to your WaitCallback method.

+1
source

The most convenient way is to use a lambda expression:

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

This is the smartest way to use this API.

The C # compiler will generate a class inside. This method is (practically) as fast as using the class explicitly.

+1
source

Using a lambda expression is really the easiest way.

However, do not use the ThreadPool.QueueUserWorkItem state argument to pass arguments should be considered as an anti-pattern:

The following works sequentially in my application:

 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 on my hardware it doesn’t work consistently:

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

... since it cannot provide all the data in the input array. (Tested with VS2010 and .NET v4.0.30319)

0
source

Source: https://habr.com/ru/post/1301841/


All Articles