2012-03-27 47 views
0

我有一個執行功能的異步任務。該函數不包含任何循環語句,而是在sql server上執行一系列sql命令。現在,我的窗口上有一個可以取消這些sql操作的按鈕。換句話說,取消整個異步任務。如何取消沒有執行任何基於循環的語句的任務

我知道這項技術需要CancellationTokenSource和CancellationToken取消任務,但我在互聯網上看到很多例子,並且他們都顯示任務正在執行的函數包含循環語句,他們正在檢查它們爲IsCancellationRequested布爾屬性。但就我而言,情況並非如此。我的函數沒有任何循環語句,我可以檢查這個布爾屬性。

請提出任何方法/技巧。

任何幫助將是非常可觀......

Thanx提前...

+0

如果您取消完成的命令時這些命令不在事務中,我相信它們將不會回滾。爲什麼用戶會取消?如果這是一個長時間運行的任務,請考慮使用Progress的BackGroundWorker,以便可以報告已處理了多少個sql語句。 – Paparazzi 2012-03-27 14:27:49

+0

@Blam,也許這些都是'SELECT',所以將它們回滾並不重要? – svick 2012-03-27 16:18:47

回答

1

嗯,有真的只有三個基本程序流:序列(步驟1,步驟2等),選擇(if-type語句)和迭代(循環)。

如果你沒有任何循環,你只剩下選擇和順序。這意味着你的代碼很可能將最終看起來像(僞代碼,很明顯):

perform sql (statement1) 
if IsCancellationRequested: return 

perform sql (statement2) 
if IsCancellationRequested: return 
: 
: 
perform sql (statementN) 
if IsCancellationRequested: return 

換句話說,沒有循環,有把支票在那裏它會被稱爲很多沒有單一方便的地方次,你必須自己多次打電話。根據調用的次數,在循環中調用它並沒有真正的區別。


如果你的問題是,你不喜歡在你的源代碼中穿插許多檢查的想法,你可以創建一個函數來爲你做,是這樣的:

def execSql (sqlStatement): 
    perform sql (sqlStatement) 
    return IsCancellationRequested 

那麼你的線條變得:

if (perform sql (statement1)): return 
if (perform sql (statement2)): return 
: 
if (perform sql (statementN)): return 

現在,你也許可以通過把語句轉換成某種形式的集合,這樣一來,你會添加循環只需要編寫一個支票/退貨。但這意味着你現在做事情的方式會發生更大的變化。

0

你應該在你的代碼中檢查它。你的例子(你看到的例子),因此它檢查每次迭代的取消。既然你不需要,你將不得不手動選擇當你想檢查用戶是否取消它。既然你有查詢,也許在每個查詢之後,或每2或3個查詢。當你需要它時。

+0

@gbianchi ...看到的東西是,用戶可以通過點擊按鈕在ANYTIME取消任務。所以保持每行後的檢查,我認爲這是一個荒謬的想法... – Uday0119 2012-03-27 14:18:33

+0

那麼..施工檢查後,每一行;)但你只寫了一次:) – gbianchi 2012-03-27 14:19:54

0

所以讓他們!

簡單的例子(如你喜歡,你可以擴展它):

List<string> _sqls = new List<string>(); 
_sqls.Add("Select ... "); 
_sqls.Add("Update ... "); 
_sqls.Add("Select ... "); 

foreach (var sql in _sqls) 
{ 
    Execute(sql); 
    if (IsCancellationRequested) 
    { 
     // Make some rollback 
     return; 
    } 
} 

爲了更好的體驗,你可以使用List<Func<..>>List<Action<..>>代替List<string>甚至拿出查詢,生成器,工廠方法設計模式。