2012-09-28 38 views
8

Tôi có vòng lặp while trong dịch vụ cửa sổ chạy trong khoảng thời gian x lần và bắt đầu x cuộc gọi điện thoại sau khi đọc chúng từ một số tệp. Bây giờ, nếu tôi muốn tạo giao diện người dùng cung cấp tùy chọn để dừng các cuộc gọi điện thoại, tức là ngắt vòng lặp while ngay cả trước khi hoàn thành. Làm thế nào tôi sẽ làm điều đó?Phá vỡ vòng lặp trong khi sử dụng sự kiện bên ngoài

Cho phép giả sử tôi có chức năng.

DialCalls(x) 
{ 
    for(int i= 0 ; i<x ; i++) 
    { 
    // Initiate call 
    } 
} 

Có thể có 2,3 chức năng DialCalls chạy cùng lúc trong các chủ đề khác nhau khi tôi cũng đã thực hiện luồng trong ứng dụng. Vì vậy, về cơ bản cách tốt nhất để phá vỡ vòng lặp từ một trang web có thể là gì.

+1

Đối với những người đề xuất 'dễ bay hơi': http://blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three.aspx –

Trả lời

6

Sử dụng task hủy (mới trong .net 4):

[Fact] 
public void StartAndCancel() 
{ 
    var cancellationTokenSource = new CancellationTokenSource(); 
    var token = cancellationTokenSource.Token; 
    var tasks = Enumerable.Repeat(0, 2) 
          .Select(i => Task.Run(() => Dial(token), token)) 
          .ToArray(); // start dialing on two threads 
    Thread.Sleep(200); // give the tasks time to start 
    cancellationTokenSource.Cancel(); 
    Assert.Throws<AggregateException>(() => Task.WaitAll(tasks)); 
    Assert.True(tasks.All(t => t.Status == TaskStatus.Canceled)); 
} 

public void Dial(CancellationToken token) 
{ 
    while (true) 
    { 
     token.ThrowIfCancellationRequested(); 
     Console.WriteLine("Called from thread {0}", Thread.CurrentThread.ManagedThreadId); 
     Thread.Sleep(50); 
    } 
} 

http://blogs.msdn.com/b/csharpfaq/archive/2010/07/19/parallel-programming-task-cancellation.aspx Nhiệm vụ nuốt ngoại lệ để có một số ngẫu nhiên để đến, có lẽ như IDisposable? About task exceptions

+1

đây là câu trả lời hay (vì vậy +1), nhưng bạn có thể cải thiện nó bằng cách bao gồm một vài đoạn trích có liên quan từ bài viết. –

4

Bạn có thể viết câu lệnh if bên trong vòng lặp của mình để thăm dò trạng thái của sự kiện bên ngoài.

Ví dụ, bạn có thể có một lá cờ:

bool break_out = false;

Và trong trường hợp bên ngoài của bạn, bạn đặt cờ break_out true:

break_out = true;

Bây giờ trong vòng lặp của bạn, bạn có thể có:

DialCalls(x) 
{ 
    for(int i= 0 ; i<x ; i++) 
    { 
    // Initiate call 

    if (break_out) { 
     break; 
    } 
    } 
} 
3

Tạo một sự kiện hỗ trợ hủy:

public event EventHandler<CancelEventArgs> Call; 

Nếu thuê bao tồn tại và hủy bỏ nó, đừng gọi:

while (true) 
{ 
    var e = new System.ComponentModel.CancelEventArgs(); 
    if (Call != null) 
    { 
     Call(this, e); 
    } 
    if (!e.Cancel) 
    { 
     // Initiate call 
    } 
    else 
    { 
     break; 
    } 
} 
0

Bằng cách sử dụng một biến kể khi để phá vỡ.

private bool _cancel; 

void DialCalls(...) 
{ 
    for (int i=0; i<x; i++) 
    { 
     ... 
     if (_cancel) break; 
     .... 
    } 
} 

private void SomeEventHandler(object sender, EventArgs e) 
{ 
    _cancel = true; 
} 

hoặc

for (int i=0; i<x && !_cancel; i++) 
0

Có một biến toàn cục là biến động

public static volatile bool stop;  
stop=False; 

DialCalls(x) 
{ 
    for(int i= 0 ; i<x && !stop ; i++) 
    { 
    // Initiate call 
    } 
} 

On Button Click => stop =True; 
0

Thực hiện một thiết bị đầu cuối trên dịch vụ mà chấp nhận một thông điệp rằng Toggles a/boolean tĩnh toàn cầu (hoặc một số khác) biến và có vòng lặp bên trong DialCalls kiểm tra biến đã nói ở đầu mỗi lần lặp. Nó sẽ không làm gián đoạn bất kỳ cuộc gọi điện thoại hiện đang trong tiến trình, nhưng tôi cá là bạn không muốn dịch vụ treo lên ở giữa cuộc gọi, chỉ cần không chuyển sang tiếp theo. Điều này sẽ gián đoạn cho tất cả các chủ đề là tốt; chỉ cần đảm bảo biến biến là an toàn cho chuỗi (ví dụ: sử dụng từ khóa volatile).

1
while (!_shouldStop) { /* work in progress */ } 

và trong Stop() phương pháp mà phải được trên lớp lao động tương tự biến bool phải được thiết lập như là sự thật.

Ngoài ra, nếu có bất kỳ người phục vụ nào (như AutoResetEvent), họ phải là .Set();.

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