2014-02-24 44 views
1

我有一個後臺工作人員,負責下載大量小文件並將其保存在硬盤上。爲了給你一個規模的想法,3000萬個文件。優雅地殺死一個耗時太長的方法

後臺工作者是可取消的,我可以取消就好了,一旦我開始下載文件。但是在調用外部dll方法時,我無法取消該方法,該方法告訴我要下載哪些文件。我有一個外部DLL與我調用的方法返回這個長長的文件列表。完成這種單一方法可能需要幾個小時。

我真的需要能夠取消這個電話。例如,用戶會因所花費的時間和點擊取消而感到沮喪。現在,我需要等到該方法完成後才能取消。

下面是一個例子:

void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    TimeIntensiveMethod(); // Can take up to an hour - can't cancel it 

    for (int i = 0; i < 1000; i++) 
    { 
     if (worker.CancellationPending) 
      break; 

     ShortDurationMethod(); // The wait to complete before cancelling is unperceivable 
    } 
} 

在這個例子中,我希望能夠在TimeIntensiveMethod取消,而它在工作的中間。這可能嗎?

+0

一個非常好的例子,如何包裝這個任務,並殺死任務:http://msdn.microsoft .com/en-us/library/dd997396%28v = vs.110%29.aspx – Haney

+1

@DavidHaney:如果我理解正確,對'TimeIntensiveMethod'的整體調用可以防止這種情況發生一個好方法,除非它可以被重寫以支持取消。 – spender

+0

@spender你可能是對的。我們對「TimeIntensiveMethod」一無所知。 – Haney

回答

3

唯一或多或少可靠的方法來取消本機代碼的執行,是在一個單獨的進程中運行它,並停止該進程。

只有當該進程沒有執行I/O時,它才能可靠地工作。如果是這樣,誰知道如果在I/O操作過程中被中斷會發生什麼。

有幾種方法可以在單獨的進程中運行調用,並且整理參數並返回整個進程邊界的值。使用WCF是一種選擇。使用managed add-in framework是另一個(雖然我不會推薦它)。使用System.Diagnostics.Process類運行控制檯程序並捕獲輸出流可能是最佳選擇。

-1

作爲進程外調用的一種簡單和無憂的替代方法,您可以簡單地啓動一個新線程,在其中進行調用,並在您的主線程中終止該線程(如果您喜歡的話)。

你有一些資源泄漏,但如果它是一個用戶驅動的應用程序,它可以接受......

編輯:

另外一個方法是故意打碎的過程從後面,例如,如果它是文件枚舉,鎖定一些文件,使枚舉失敗,並退出...

+0

只能合作完成一個線程。 'Thread.Abort'是非常不安全的。 – usr

+0

如果DLL中的代碼是本機代碼,則Thread.Abort()將不起作用。正如@usr指出的那樣,即使使用託管代碼,也是不可靠的。 –

+0

是的。正如我所指出的:無憂無慮。如果你能擺脫它,那就去做吧。 –