簡體   English   中英

線程在c#中

[英]Threading in c#

如何使用C#中的線程調用一個帶兩個參數的函數? 我必須從另一個函數調用StartDNIThread(string storeID,string queryObject)。我必須傳遞兩個值。它們都是字符串

你的選擇是:

  • 將參數封裝在新類中,並將該方法用於委托到該類中。
  • 使用匿名函數(匿名方法或lambda表達式)自動對捕獲的變量執行相同的操作。

后者通常更容易。 你還沒有展示你在線程中做了什么,但你可能會做以下事情:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM