2009-06-28 34 views
10

Tôi đang tìm kiếm một cách để khởi động lại một chủ đề đó đã được chặn lại bởi Abort() ..Khởi động lại a thread trong .NET (sử dụng C#)

public partial class MyProgram : Form 
{ 
    private Thread MyThread = new Thread(MyFunction); 
    private System.Windows.Forms.Button startStopBtn = new System.Windows.Forms.Button(); 
    public MyProgram() 
    { 
    MyThread.Start(); 
    startStopBtn += new EventHandler(doStop); 
    startStopBtn.Text = "Stop"; 
    } 
    private static void MyFunction() 
    { 
    // do something 
    } 
    private void doStop(object sender, EventArgs e) 
    { 
    MyThread.Abort(); 
    startStopBtn -= new EventHandler(doStop); 
    startStopBtn += new EventHandler(doStart); 
    startStopBtn.Text = "Start"; 
    } 
    private void doStart(object sender, EventArgs e) 
    { 
    MyThread.Start(); // << Error returned when clicking the button for 2nd time 
    startStopBtn -= new EventHandler(doStart); 
    startStopBtn += new EventHandler(doStop); 
    startStopBtn.Text = "Stop"; 
    } 
} 

Bất kỳ ý tưởng?

Trả lời

12

Chỉ cần thêm MyThread = chủ đề mới (MyFunction) trước khi gọi MyThread.Start() trong doStart(). Không tạo luồng bên ngoài các phương thức của bạn, không gian có suy nghĩ cho khai báo.

CHỈNH SỬA: Xin lưu ý rằng việc giết một sợi chỉ với chuỗi.Xoá() có thể rất nguy hiểm. Bạn nên cố gắng thực hiện đa luồng sạch, như Groo được mô tả trong bài đăng của mình.

+0

Câu trả lời này là giải pháp khác hơn là câu trả lời thực. thậm chí không giải thích lý do tại sao anh ta nhận được lỗi Groo đã đúng, – Trap

+3

Bạn nói đúng, nhưng khi tôi là một người mới bắt đầu lập trình, tôi đã gặp một số vấn đề tương tự, tôi đã đọc nhiều giải pháp như vậy. bạn hoàn toàn đúng, giải pháp của tôi chỉ là một cách giải quyết.Nhưng cơ chế mà groo mô tả quá phức tạp để tôi hiểu trong thời gian lập trình-newb của tôi. Vì vậy, tôi khó khăn hơn, có thể tốt hơn là cung cấp một câu trả lời đơn giản (hoặc Workaround workaround) cho một lập trình viên không có nhiều kinh nghiệm – Emiswelt

+0

Đây là những thứ làm cho các lập trình viên xấu Họ không đầu tư đủ thời gian để hiểu những gì họ đang làm. o sẽ làm sạch Thread.Abort mess của bạn khi bạn đi? –

2

Không, không có, nhưng tại sao bạn muốn? Chỉ cần khởi động một luồng mới, với cùng một ThreadStart, và cùng một tham số (nếu có).

6

Câu trả lời đơn giản là bạn không thể. Khi một chuỗi đã bị hủy, bạn không thể khởi động lại nó. Chỉ cần tạo một phương thức hoặc một cái gì đó, trả về một đối tượng Thread chỉ là cách bạn cần nó. Khi bạn cần một Thread mới, chỉ cần lấy nó từ phương thức đó.

29

Khi bạn đã hủy bỏ chủ đề của mình, bạn không thể bắt đầu lại.

Nhưng vấn đề thực tế của bạn là bạn đang hủy bỏ chuỗi của bạn. Bạn nên never use Thread.Abort().

Nếu chuỗi của bạn bị tạm dừng và tiếp tục nhiều lần, bạn nên cân nhắc sử dụng các cơ chế khác (ví dụ như AutoResetEvent).

[EDIT]

Giải pháp đơn giản nhất để hủy bỏ một chủ đề, như đã đề cập bởi Ian Griffiths trong liên kết ở trên, là:

Cách tiếp cận tôi luôn khuyên là chết đơn giản. Có trường volatile bool hiển thị cả chuỗi công việc và chuỗi giao diện người dùng của bạn. Nếu người dùng nhấp vào hủy, đặt cờ này. Trong khi đó, trên chuỗi công nhân của bạn, kiểm tra cờ theo thời gian. Nếu bạn thấy nó được thiết lập, hãy dừng những gì bạn đang làm.

Điều duy nhất mà bạn cần phải làm gì để làm cho nó hoạt động đúng, là để sắp xếp lại phương pháp nền của bạn để nó chạy trong một vòng lặp - vì vậy mà bạn định kỳ có thể kiểm tra nếu lá cờ của bạn đã được thiết lập bởi một chủ đề khác nhau.

Nếu bạn cần tạm dừng và tiếp tục chức năng cho cùng một chuỗi công nhân, thay vì cách tiếp cận đơn giản volatile bool, bạn có thể tiếp cận một cách phức tạp hơn, một cấu trúc đồng bộ hóa như AutoResetEvent. Các lớp này cũng cung cấp một cách để đưa luồng công nhân vào giấc ngủ trong một khoảng thời gian cụ thể (hoặc không xác định) giữa các tín hiệu từ chuỗi không phải của người lao động.

This thread chứa ví dụ cụ thể với phương pháp Bắt đầu, Tạm dừng, Tiếp tục và Dừng. Lưu ý cách ví dụ của Brannon không bao giờ hủy bỏ chuỗi. Nó chỉ kích hoạt một sự kiện, và sau đó đợi cho đến khi sợi kết thúc một cách duyên dáng.

0

Nếu bạn thực sự cần phải ngắt chức năng chuỗi và tiếp tục, bạn nên đặt điều kiện và sau đó kiểm tra định kỳ trong khi xử lý.

Điều đó sẽ cho phép bạn ngừng xử lý trong một khoảng thời gian và sau đó tiếp tục.

Tôi đã sử dụng sự kiện và Cuộc gọi chờ để hoàn thành nhiệm vụ tương tự.

0

Cách dễ nhất là không hủy chủ đề.

-3

Tôi thực sự không hiểu tại sao mọi người cung cấp thông tin nếu họ không biết đó là chính xác .. Làm thế nào một lập trình viên thực sự có thể tạm dừng hoặc ngừng xử lý một chuỗi đôi khi và sau đó phát hành nó và do đó làm cho mã dễ bị tổn thương .. @ Brad-- m xin lỗi .. nhưng ý tưởng của bạn không tốt .. @ loạn nhịp - Bạn cần phải làm việc trên con đường của bạn để tiếp cận mọi thứ ..

BFree có phần đúng nếu bạn nhận được cùng một cách anh ấy muốn nói .. Bạn chỉ cần tuyên bố lại rằng ..

dưới đây là ví dụ:

Public Shared Sub ResetAbort() 

    Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName)) 

    YourThreadName.Start() 

    Thread.Sleep(2000) 

    YourThreadName.Abort() 

End Sub 

Bây giờ bạn có thể sử dụng Sub này ở bất cứ đâu bạn muốn bắt đầu chuỗi. Nó sẽ tự động hủy bỏ chủ đề.

Nếu bạn muốn bắt đầu thread trên Button1_Click() sự kiện và ngăn chặn nó trên button2_Click() sự kiện sử dụng này:

trong Button1_Click() sự kiện

Dim ThreadPleaseWait As New Thread(New ThreadStart(AddressOf YourSubName)) 

    YourThreadName.Start() 

trong button2_Click() sự kiện

YourThreadName.Start() 

làm theo cách này, bạn sẽ hủy bỏ chuỗi bạn ở nơi bạn muốn và sẽ khởi chạy lại. Bạn cũng có thể sử dụng thuộc tính YourThreadName.ThreadState.Running để kiểm tra xem luồng có đang chạy hay không (Chỉ cần tránh nhiều trường hợp cùng một chuỗi .....

+5

Vui lòng sửa định dạng của bạn. Ngoài ra, trong khi bạn đang chỉnh sửa nó, bạn có thể muốn làm cho nó ít hiếu chiến hơn một chút. Mặc dù bạn không thích từ "không", bạn * không thể khởi động lại một chuỗi bị hủy *. Những gì OP hỏi là không thể. Ngoài ra, Thread.Abort() được coi là có hại. Có nhiều cách tốt hơn để kiểm soát việc thực thi luồng. Bạn không phục vụ người hỏi bằng cách để anh ta tiếp tục làm những điều xấu. Tốt hơn là cung cấp các lựa chọn thay thế phục vụ yêu cầu của mình mà không phải chịu rủi ro tương tự. – Will

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