如何使用C#中的线程调用一个带两个参数的函数? 我必须从另一个函数调用StartDNIThread(string storeID,string queryObject)。我必须传递两个值。它们都是字符串
答案 0 :(得分:8)
您的选择是:
后者通常更容易。你没有展示你在线程中做了什么,但是你可能会做类似的事情:
string storeID = "...";
string queryObject = "...";
Thread t = new Thread(() => StartDNIThread(storeID, queryObject));
t.Start();
请注意,由于捕获了变量,因此在您知道线程实际已启动之后,才应更改这些值。您可以使用匿名函数仅使用的捕获变量来解决此问题:
string storeID = "...";
string queryObject = "...";
string storeIDCopy = storeID;
string queryObjectCopy = queryObject;
Thread t = new Thread(() => StartDNIThread(storeIDCopy, queryObjectCopy));
t.Start();
// You can now change storeID and queryObject freely
如果你在循环中做任何事情,这一点尤为重要,因为循环变量本身会发生变化。例如:
foreach (string storeID in stores)
{
string storeIDCopy = storeID;
Thread t = new Thread(() => StartDNIThread(storeIDCopy, queryObject));
t.Start();
}
如果您正在使用线程池或任何其他方式启动线程,则模式基本相同。
答案 1 :(得分:6)
ThreadStart threadStart = delegate{StartDNIThread(string storeID, string queryObject);};
Thread thread = new Thread(threadStart);
thread.Start();
或者使用lambdas:
ThreadStart threadStart = () => StartDNIThread(string storeID, string queryObject);
Thread thread = new Thread(threadStart);
thread.Start();
答案 2 :(得分:2)
使用线程池:
string str1 = "str1";
string str2 = "str2";
ThreadPool.QueueUserWorkItem(state =>
{
Console.WriteLine("{0}:{1}", str1, str2);
});
如果您想进行涉及UI的替代线程处理,最好使用BackgroundWorker。
答案 3 :(得分:1)
您可以使用ParameterizedThreadStart委托。 这个委托需要一个带有一个参数(tyoe对象)的方法。因此,实际上您可以使用自定义类型(类或结构),其中包含要传递给ParameterizedThreadStart的2个变量。
像这样:
Thread t = new Thread (new ParameterizedThreadStart (DoWork));
t.Start(new MyType(storeId, queryObject));
但是,在这种情况下,我更愿意以另一种方式来做。我更喜欢创建一个自定义的“任务”类型,它抽象所有这些东西。 像这样:
public class Task
{
private readonly int _storeId;
private readonly string _queryObject;
public Task(int storeId, string queryObject)
{
_storeId = storeId;
_queryObject = queryObject;
}
public void Start()
{
Thread t = new Thread (new ThreadStart(DoWork));
t.Start();
}
private void DoWork()
{
// Do your thing here.
}
}
答案 4 :(得分:0)
我倾向于创建一个类似于以下
的任务对象class myClass
{
public void CallingCode()
{
ProcessRequest pr1 = new ProcessRequest("storeD","queryObj");
ThreadStart ts1 = new ThreadStart(pr1.Go);
Thread wrk = new Thread(ts1);
wrk.Start();
}
}
class ProcessRequest
{
private string storeD;
private string queryObj;
public ProcessRequest(string storeD, string queryObj)
{
this.stroreD = storeD;
this.queryObj = queryObj;
}
public void Go()
{
try
{//your processing code here you can access $this->storeD and $this->queryObj
}
catch (Exception ex)
{
}
}
}
答案 5 :(得分:0)
我个人喜欢代表路线:
private delegate void StartDNIThreadDelegate(string storeID, string queryObject);
private static void Main()
{
string storeID = "...";
string queryObject = "...";
StartDNIThreadDelegate startDNIThread = new StartDNIThreadDelegate(StartDNIThread);
IAsyncResult result = startDNIThread.BeginInvoke(storeID, queryObject, new AsyncCallback(StartDNIThreadDone), startDNIThread);
// Do non-threaded stuff...
result.AsyncWaitHandle.WaitOne(); // wait for thread to finish.
}
private static void StartDNIThread(string storeID, string queryObject)
{
// Do StartDNIThreading stuff.
}
private static void StartDNIThreadDone(IAsyncResult result)
{
StartDNIThreadDelegate startDNIThread = (StartDNIThreadDelegate)result.AsyncState;
// Do after thread finished cleanup.
startDNIThread.EndInvoke(result);
}