2009-03-11 26 views
8

Người dùng HTML loại ứng dụng của tôi vào một điều khiển TextBox.Làm cách nào để hủy và khởi động lại đúng quy trình BackgroundWorker?

Tôi muốn ứng dụng của mình xác thực tính năng nhập của họ trong nền.

Vì tôi không muốn búa dịch vụ xác thực, tôi đã cố gắng xây dựng trong một giây chậm trễ trước mỗi lần xác thực.

Tuy nhiên, dường như tôi không thể ngắt chính xác quy trình BackgroundWorker đã chạy.

trực quan mã cơ bản của tôi:

 
Sub W3CValidate(ByVal WholeDocumentText As String) 

    'stop any already-running validation 
    If ValidationWorker.IsBusy Then 
     ValidationWorker.CancelAsync() 
     'wait for it to become ready 
     While ValidationWorker.IsBusy 
      'pause for one-hundredth of a second 
      System.Threading.Thread.Sleep(New TimeSpan(0, 0, 0, 0, 10)) 
     End While 
    End If 

    'start validation 
    Dim ValidationArgument As W3CValidator = New W3CValidator(WholeDocumentText) 
    ValidationWorker.RunWorkerAsync(ValidationArgument) 

End Sub 

Dường như sau khi gọi CancelAsync BackgroundWorker tôi(), IsBusy của nó không bao giờ trở thành False. Nó bị mắc kẹt trong một vòng lặp vô hạn.

Tôi đang làm gì sai?

+0

Ý tôi là thoát khỏi thủ tục nếu e.Cancelled là đúng. – Pat

Trả lời

0

Tôi tìm thấy câu trả lời trong bài viết này:

BackgroundWorker Closure and Overridable Task bởi Patrick Smacchia

Tôi đã thích nghi code của mình:

 
Private _ValidationArgument As W3CValidator 

Sub W3CValidate(ByVal WholeDocumentText As String) 
    If _ValidationArgument IsNot Nothing Then 
     _ValidationArgument = New W3CValidator(WholeDocumentText) 
     Exit Sub 
    End If 
    If Not ValidationWorker.IsBusy Then 
     ValidationWorker.RunWorkerAsync(New W3CValidator(WholeDocumentText)) 
     Exit Sub 
    End If 
    _ValidationArgument = New W3CValidator(WholeDocumentText) 
    ValidationWorker.CancelAsync() 
    Dim TimerRetryUntilWorkerNotBusy As New Windows.Threading.DispatcherTimer 
    AddHandler TimerRetryUntilWorkerNotBusy.Tick, AddressOf WorkTicker 
    TimerRetryUntilWorkerNotBusy.Interval = New TimeSpan(1) '100 nanoseconds 
    TimerRetryUntilWorkerNotBusy.Start() 
End Sub 

Sub WorkTicker(ByVal sender As Object, ByVal e As System.EventArgs) 
    If ValidationWorker.IsBusy Then 
     Exit Sub 
    End If 
    DirectCast(sender, Windows.Threading.DispatcherTimer).Stop() 
    ValidationWorker.RunWorkerAsync(_ValidationArgument) 
    _ValidationArgument = Nothing 
End Sub 
1

Trong nền worker process vòng lặp của bạn, bạn cần phải kiểm tra cho
backgroundWorkerPageProcess.CancellationPending
và thoát tương ứng. Sau đó, một khi nó tồn tại vòng lặp while của bạn làBusy nên được gắn cờ cho phù hợp.

Cập nhật: Sau khi bạn đặt Hủy = đúng là bạn đã quay trở lại phương pháp chưa? spitballing here Cập nhật 2: Bạn có cờ WorkerSupportsCancellation được đặt thành true trên nền? Cũng trong phương thức hoàn thành công nhân, hãy quay trở lại nếu e.Cancelled .... thêm spitballs

Cập nhật 3: sau khi một số kiểm tra và biên soạn của riêng tôi xuất hiện điều chết tiệt không bao giờ thoát ra khỏi isbusy trong cùng một phương pháp. -Một tùy chọn là tắt nút trong khi bận và có nút khác để hủy, chỉ để người dùng có thể đánh dấu lại xác thực. -Hoặc phương thức hoàn thành công nhân của bạn nếu (e.Cancelled) gọi phương thức xác thực của bạn bằng văn bản thích hợp ....

hoặc là cách phá sản. Xin lỗi vì không có nhiều trợ giúp ở đây.

+0

Đó cũng là những gì tôi mong đợi. Phương thức DoWork() của tôi đặt e.Cancel = True nếu DirectCast (người gửi, BackgroundWorker) .CancellationPending. Nhưng IsBusy không bao giờ trở lại Sai bất kể. –

+0

DoWork của tôi() chạy "e.Cancel = True" rồi ngay lập tức "Thoát Sub". My RunWorkerCompleted() chỉ đơn giản là làm tất cả nó làm việc bên trong một điều kiện Nếu: "Nếu không e.Cancelled Sau đó ... End Nếu End Sub". Phải làm nhiều hơn? –

+0

Có. Tôi đã đặt ValidationWorker.WorkerSupportsCancellation = True. Ý bạn là "trả lại nếu e.Cancelled"? –

8

Hãy thử một cái gì đó như thế này:

bool restartWorker = false; 

    void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
        // add other code here 
     if (e.Cancelled && restartWorker) 
     { 
      restartWorker = false; 
      backgroundWorker1.RunWorkerAsync(); 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     if (backgroundWorker1.IsBusy) 
     { 
      restartWorker = true; 
      backgroundWorker1.CancelAsync(); 
     } 
     else 
      backgroundWorker1.RunWorkerAsync(); 
    } 
+1

Bạn sẽ sửa đổi điều này để chuyển các tham số mới vào RunWorkerAsync như thế nào? – tofutim

+0

Tôi thấy câu trả lời này hữu ích cho một TextBox tìm kiếm các đề xuất từ ​​cơ sở dữ liệu.Để truyền các tham số, sử dụng RunWorkerAsync (đối tượng) ở vị trí đầu tiên và vì RunWorkerCompleted cũng đang chạy trong chuỗi giao diện người dùng, truyền giá trị mới ở đó. –

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