2009-09-01 41 views
25

Cách chia sẻ dữ liệu giữa các luồng khác nhau Trong C# mà không sử dụng các biến tĩnh? Chúng ta có thể tạo ra một máy móc như vậy bằng cách sử dụng thuộc tính?Cách chia sẻ dữ liệu giữa các luồng khác nhau Trong C# bằng AOP?

Trợ giúp lập trình hướng Aspect trong các trường hợp như vậy?

Để đạt được điều này, tất cả các luồng khác nhau sẽ hoạt động trên một đối tượng?

+2

Bạn có thể truy cập bất kỳ biến nào trong phạm vi từ chuỗi. ví dụ. 2 luồng có thể gọi cùng một hàm và truy cập cá thể thành viên/biến tĩnh. Chia sẻ là tầm thường, đồng bộ hóa truy cập biến trên nhiều luồng là nhiệm vụ khác biệt hơn. – Gishu

+1

Chúng tôi đang cố gắng đọc đối tượng có sẵn trong một chủ đề thành một chuỗi khác và chúng tôi có một hạn chế để duy trì biến toàn cầu/tĩnh, có một số ý tưởng hay để đạt được nó không? –

+0

Bạn không truy cập chủ đề như vậy. Thay vào đó bạn truy cập các đối tượng mà các luồng có thể thấy. Nếu mã chạy trong một luồng có thể truy cập một cá thể đối tượng hoặc dữ liệu tĩnh, nó có thể thay đổi nó. Nếu một luồng khác có thể thấy trường hợp đó hoặc dữ liệu tĩnh thì bạn đã truyền đạt giữa hai luồng. – djna

Trả lời

5

Bạn có thể chuyển đối tượng làm đối số cho Thread.Start và sử dụng nó làm bộ nhớ dữ liệu được chia sẻ giữa chuỗi hiện tại và chuỗi khởi tạo.

Bạn cũng có thể truy cập trực tiếp (với khóa khóa thích hợp của khóa học) các thành viên dữ liệu của bạn, nếu bạn bắt đầu chuỗi bằng cách sử dụng biểu mẫu của đại biểu ThreadStart.

Bạn không thể sử dụng thuộc tính để tạo dữ liệu được chia sẻ giữa các chuỗi. Bạn có thể sử dụng các cá thể thuộc tính được gắn vào lớp của bạn như là một lưu trữ dữ liệu, nhưng tôi không thấy cách nó tốt hơn sử dụng các thành viên dữ liệu tĩnh hoặc cá thể.

+2

Để sử dụng như một kho lưu trữ dữ liệu được chia sẻ một lần nữa cần phải đi cho một số biến tĩnh/toàn cầu? –

+0

Mã bắt đầu luồng rõ ràng có tham chiếu đến đối tượng được truyền như một tham số cho Thread.Start. Thủ tục thread cũng có một tham chiếu đến đối tượng đó. Vì vậy, nhưng các đoạn mã có thể ghi vào nó mà không có đối tượng đó phải là một biến tĩnh. –

+2

vâng .. tôi hiểu rồi ..bạn sẽ vui lòng viết một số đoạn mã để hiểu rõ hơn –

16

Bạn không thể đánh bại sự đơn giản của hàng đợi tin nhắn bị khóa. Tôi nói đừng lãng phí thời gian của bạn với bất cứ điều gì phức tạp hơn.

Đọc trên báo cáo khóa.

lock

EDIT

Dưới đây là một ví dụ của đối tượng Microsoft Queue bọc vì vậy tất cả các hành động chống lại nó là chủ đề an toàn.

public class Queue<T> 
{ 
    /// <summary>Used as a lock target to ensure thread safety.</summary> 
    private readonly Locker _Locker = new Locker(); 

    private readonly System.Collections.Generic.Queue<T> _Queue = new System.Collections.Generic.Queue<T>(); 

    /// <summary></summary> 
    public void Enqueue(T item) 
    { 
     lock (_Locker) 
     { 
      _Queue.Enqueue(item); 
     } 
    } 

    /// <summary>Enqueues a collection of items into this queue.</summary> 
    public virtual void EnqueueRange(IEnumerable<T> items) 
    { 
     lock (_Locker) 
     { 
      if (items == null) 
      { 
       return; 
      } 

      foreach (T item in items) 
      { 
       _Queue.Enqueue(item); 
      } 
     } 
    } 

    /// <summary></summary> 
    public T Dequeue() 
    { 
     lock (_Locker) 
     { 
      return _Queue.Dequeue(); 
     } 
    } 

    /// <summary></summary> 
    public void Clear() 
    { 
     lock (_Locker) 
     { 
      _Queue.Clear(); 
     } 
    } 

    /// <summary></summary> 
    public Int32 Count 
    { 
     get 
     { 
      lock (_Locker) 
      { 
       return _Queue.Count; 
      } 
     } 
    } 

    /// <summary></summary> 
    public Boolean TryDequeue(out T item) 
    { 
     lock (_Locker) 
     { 
      if (_Queue.Count > 0) 
      { 
       item = _Queue.Dequeue(); 
       return true; 
      } 
      else 
      { 
       item = default(T); 
       return false; 
      } 
     } 
    } 
} 

EDIT 2

Tôi hy vọng ví dụ này giúp. Hãy nhớ rằng đây là xương trần. Sử dụng những ý tưởng cơ bản này, bạn có thể khai thác sức mạnh của chủ đề một cách an toàn.

public class WorkState 
{ 
    private readonly Object _Lock = new Object(); 
    private Int32 _State; 

    public Int32 GetState() 
    { 
     lock (_Lock) 
     { 
      return _State; 
     } 
    } 

    public void UpdateState() 
    { 
     lock (_Lock) 
     { 
      _State++; 
     } 
    } 
} 

public class Worker 
{ 
    private readonly WorkState _State; 
    private readonly Thread _Thread; 
    private volatile Boolean _KeepWorking; 

    public Worker(WorkState state) 
    { 
     _State = state; 
     _Thread = new Thread(DoWork); 
     _KeepWorking = true;     
    } 

    public void DoWork() 
    { 
     while (_KeepWorking) 
     { 
      _State.UpdateState();     
     } 
    } 

    public void StartWorking() 
    { 
     _Thread.Start(); 
    } 

    public void StopWorking() 
    { 
     _KeepWorking = false; 
    } 
} 



private void Execute() 
{ 
    WorkState state = new WorkState(); 
    Worker worker = new Worker(state); 

    worker.StartWorking(); 

    while (true) 
    { 
     if (state.GetState() > 100) 
     { 
      worker.StopWorking(); 
      break; 
     } 
    }     
} 
+0

Nó không giống như một hàng đợi tin nhắn phù hợp cho bất kỳ mục đích nào ... – Thorarin

+0

Thậm chí không chuyển tin nhắn? – ChaosPandion

+1

Chúng tôi đang cố gắng để đọc các đối tượng có sẵn trong một chủ đề vào một chủ đề khác, và chúng tôi có một hạn chế để duy trì biến toàn cầu/tĩnh, có một số ý tưởng tốt để đạt được nó? –

3

Khi bạn bắt đầu một chuỗi bạn đang thực hiện một phương pháp của một số lớp đã chọn. Tất cả các thuộc tính của lớp đó được hiển thị.

Worker myWorker = new Worker(/* arguments */); 

    Thread myThread = new Thread(new ThreadStart(myWorker.doWork)); 

    myThread.Start(); 

Chuỗi của bạn hiện đang ở phương thức doWork() và có thể thấy bất kỳ thuộc tính nào của myWorker, có thể là các đối tượng khác. Bây giờ bạn chỉ cần cẩn thận để đối phó với các trường hợp có một số chủ đề tất cả nhấn các thuộc tính cùng một lúc.

+0

yep Ý tưởng của bạn rất hữu ích, hãy để tôi giải thích tình huống của tôi ở đây là Chúng tôi đang cố gắng đọc đối tượng có sẵn trong một chủ đề vào một chuỗi khác và chúng tôi có một hạn chế để duy trì biến toàn cục/tĩnh, có một số ý tưởng hay không để đạt được nó? –

+0

Bạn đã không xây dựng bạn chỉ cần lặp lại câu hỏi ban đầu của bạn. – ChaosPandion

+0

Vui lòng đọc nhận xét của tôi về câu hỏi của bạn. Tôi muốn giải thích thêm nhưng tôi cần bạn giúp đỡ. – djna

7

Nhìn vào mã ví dụ sau:

public class MyWorker 
{ 
    public SharedData state; 
    public void DoWork(SharedData someData) 
    { 
     this.state = someData; 
     while (true) ; 
    } 

} 

public class SharedData { 
    X myX; 
    public getX() { etc 
    public setX(anX) { etc 

} 

public class Program 
{ 
    public static void Main() 
    { 
     SharedData data = new SharedDate() 
     MyWorker work1 = new MyWorker(data); 
     MyWorker work2 = new MyWorker(data); 
     Thread thread = new Thread(new ThreadStart(work1.DoWork)); 
     thread.Start(); 
     Thread thread2 = new Thread(new ThreadStart(work2.DoWork)); 
     thread2.Start(); 
    } 
} 

Trong trường hợp này, các lớp chủ đề MyWorker có một biến state. Chúng tôi khởi tạo nó với đối tượng cùng một đối tượng. Bây giờ bạn có thể thấy rằng hai công nhân truy cập vào cùng một đối tượng SharedData. Thay đổi được thực hiện bởi một công nhân được hiển thị cho người khác.

Bạn có một số vấn đề còn lại.Nhân viên 2 biết khi nào các thay đổi đã được thực hiện bởi nhân viên 1 và ngược lại? Làm thế nào để bạn ngăn chặn các thay đổi xung đột? Có thể đọc: this tutorial.

+1

Yap..its gần bằng nhưng không chính xác ..tại hai chủ đề bbut cùng một thể hiện của lớp myworker, cho tôi hai ví dụ của lớp MyWorker (work1 và work2) trong các chủ đề khác nhau và muốn đọc dữ liệu từ work1 trong thread2 .. làm thế nào chúng ta có thể làm điều đó? –

+0

Trong trường hợp đó, bạn sẽ cần truyền đối tượng work1 cho luồng2. Bạn có thể làm điều này bằng cách sử dụng ParameterizedThreadStart thay cho ThreadStart. – Aamir

+0

@Amir hy vọng bạn không phiền, tôi đã điều chỉnh ví dụ để phù hợp với mô tả của Jaswant – djna

Các vấn đề liên quan