[英]Threading in c#
如何使用C#中的線程調用一個帶兩個參數的函數? 我必須從另一個函數調用StartDNIThread(string storeID,string queryObject)。我必須傳遞兩個值。它們都是字符串
你的選擇是:
后者通常更容易。 你還沒有展示你在線程中做了什么,但你可能會做以下事情:
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();
}
如果您正在使用線程池或任何其他方式啟動線程,則模式基本相同。
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();
使用線程池:
string str1 = "str1";
string str2 = "str2";
ThreadPool.QueueUserWorkItem(state =>
{
Console.WriteLine("{0}:{1}", str1, str2);
});
如果要進行涉及UI的備用線程處理,最好使用BackgroundWorker 。
您可以使用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.
}
}
我傾向於創建一個類似於以下的任務對象
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)
{
}
}
}
我個人喜歡代表路線:
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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.