线程在c#中

时间:2009-09-04 13:24:39

标签: c# multithreading

如何使用C#中的线程调用一个带两个参数的函数? 我必须从另一个函数调用StartDNIThread(string storeID,string queryObject)。我必须传递两个值。它们都是字符串

6 个答案:

答案 0 :(得分:8)

您的选择是:

  • 将参数封装在一个新类中,并将该方法用于该类的委托。
  • 使用匿名函数(匿名方法或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();
}

如果您正在使用线程池或任何其他方式启动线程,则模式基本相同。

答案 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);
}