2009-09-04 23 views
5

Làm thế nào để gọi một hàm nhận hai thông số bằng cách sử dụng luồng trong C#? tôi phải gọi StartDNIThread (string StoreID, chuỗi queryObject) từ function.I khác phải vượt qua hai values.Both là chuỗiLuồng trong C#

Trả lời

6
ThreadStart threadStart = delegate{StartDNIThread(string storeID, string queryObject);}; 
Thread thread = new Thread(threadStart); 
thread.Start(); 

Hoặc với lambdas:

ThreadStart threadStart =() => StartDNIThread(string storeID, string queryObject); 
Thread thread = new Thread(threadStart); 
thread.Start(); 
+0

Tôi nhận được lỗi sau Ngoại lệ không được loại trừ của loại 'System.NullReferenceException' xảy ra trong App_Code.g2edzdox.dll Thông tin bổ sung: Tham chiếu đối tượng không được đặt thành thể hiện của đối tượng. – Janmejay

8

lựa chọn của bạn là:

  • đóng gói các thông số trong một lớp học mới, và đặt phương thức để sử dụng cho đại biểu vào lớp đó.
  • Sử dụng các chức năng ẩn danh (các phương thức ẩn danh hoặc các biểu thức lambda) để thực hiện cùng một điều tự động với các biến đã chụp.

Thông thường, điều sau sẽ dễ dàng hơn. Bạn chưa thể hiện những gì bạn đang làm với các chủ đề, nhưng bạn có thể làm điều gì đó như:

string storeID = "..."; 
string queryObject = "..."; 

Thread t = new Thread(() => StartDNIThread(storeID, queryObject)); 
t.Start(); 

Lưu ý rằng vì biến được chụp, bạn không nên thay đổi các giá trị cho đến khi bạn biết đã thực sự bắt đầu. Bạn có thể giải quyết vấn đề này bằng cách sử dụng các biến bị bắt chỉ được sử dụng bởi chức năng ẩn danh:

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 

Điều này đặc biệt quan trọng nếu bạn làm bất cứ điều gì trong vòng lặp, vì các biến vòng lặp sẽ thay đổi. Ví dụ:

foreach (string storeID in stores) 
{ 
    string storeIDCopy = storeID; 
    Thread t = new Thread(() => StartDNIThread(storeIDCopy, queryObject)); 
    t.Start(); 
} 

Nếu bạn đang sử dụng hồ bơi chủ đề hoặc bất kỳ cách bắt đầu nào khác, mẫu về cơ bản giống nhau.

+0

Upvote cho lambdas. – Rap

2

Sử dụng threadpool:

string str1 = "str1"; 
string str2 = "str2"; 
ThreadPool.QueueUserWorkItem(state => 
          { 
           Console.WriteLine("{0}:{1}", str1, str2); 
          }); 

Nếu bạn muốn làm một số chế biến thay thế sợi liên quan đến một giao diện người dùng, bạn đang sử dụng tốt nhất BackgroundWorker.

1

Có một đại biểu ParameterizedThreadStart mà bạn có thể sử dụng. Đại biểu này yêu cầu một phương pháp lấy một đối số (đối tượng tyoe). Vì vậy, trên thực tế, bạn có thể sử dụng một kiểu tùy chỉnh (lớp hoặc cấu trúc) có chứa 2 biến mà bạn muốn chuyển tới ParameterizedThreadStart.

Như thế này:

Thread t = new Thread (new ParameterizedThreadStart (DoWork)); 
t.Start(new MyType(storeId, queryObject)); 

Nhưng, trong những tình huống như vậy, tôi muốn làm điều đó theo cách khác. Tôi thích tạo một loại 'Task' tùy chỉnh, tóm tắt tất cả những thứ này. Như thế này:

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. 
    } 

} 
0

tôi có xu hướng để tạo ra một cái gì đó đối tượng nhiệm vụ như sau

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) 
     { 

     } 
    } 
} 
+0

Bạn có thể muốn thêm một số sự kiện vào đó để xem thời điểm procssing đã hoàn thành, phụ thuộc vào những gì bạn đang thực sự làm. tức là trong ProcessRequest void công khai void ProcessFinished (ProcessRequest req); sự kiện công khai ProcessFinished EFinished; vào cuối phương thức Go() của bạn: nếu (this.EFinished! = Null) EFinished (this); Bằng cách này bạn có thể xử lý nếu cần sự kiện kết thúc: pr1.EFinished + = new ProcessRequest.ProcessFinished (pr1_EFinished); void pr1_EFinished (ProcessRequest req) {} Tôi đoán có nhiều cách để làm cho con mèo này mặc dù. – Gavin

0

Cá nhân tôi như con đường đại biểu:

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