2015-02-23 71 views
1

我有以下問題:C#定時功能

我需要運行一個功能搜索(深×),基本上查找決策樹,直到一定的深度,然後返回(或葉類成員)的值類型爲Move。同時,我希望能夠「取消」執行搜索,如果它繼續太久。

如果搜索速度更快,我不必等待它也很重要。我意識到這不是一個複雜的問題,但我對C#併發控制並不熟悉。

+9

和代碼你試過迄今是...? – Jeremy 2015-02-23 11:37:10

+0

目前,我的代碼存在這樣做沒有計時器,我不知道如何修改此選項提前終止的選項。 – 2015-02-23 11:46:43

+2

你能和我們分享一段代碼嗎? – 2015-02-23 11:57:04

回答

0

下面是一個簡單的例子作爲出發點:

public class Runner 
{ 
    private Task<int> search(CancellationToken ct) 
    { 
     var t_work = Task.Factory.StartNew<int>(() => 
     { 
      int k = 0; 

      while (k < 1000) 
      { 
       if (ct.IsCancellationRequested) 
       { 
        return -1; 
       }      
       k += r.Next(200); 
       Thread.Sleep(300); 
      } 
      return k; 

     }, ct); 
     return t_work; 
    } 

    Random r = new Random(); 

    public async Task SearchAsync() 
    { 
     var timeout = TimeSpan.FromSeconds(3); 
     var cts = new CancellationTokenSource(timeout); 
     var ct = cts.Token; 
     var searchValue = await search(ct); 
     string result = (searchValue < 0) ? 
      "Search aborted without results" : "search value is: " + searchValue.ToString(); 
     Console.WriteLine(result); 
    } 
} 

,你可以用它在一個控制檯應用程序是這樣的:

Console.WriteLine("test"); 
var r = new Runner(); 
r.SearchAsync().Wait(); 
r.SearchAsync().Wait(); 
r.SearchAsync().Wait(); 
r.SearchAsync().Wait(); 
Console.WriteLine("done.."); 
+0

爲什麼downvote?這是一個被問及的定時c#函數的小例子。 – matthes 2015-02-23 21:43:55

0

我會用這一個Task,因爲它已建成在處理錯誤的機制中,取消並在任務完成時運行Continuation Tasks

假設移動,我想你在你的問題暗示的自定義返回類型:

private Task<Move> _searchTask; 
private CancellationTokenSource _searchCancellationTokenSrc; 

然後點擊一個按鈕或類似的,脫掉你的任務。這將立即返回,保持你的UI響應:

private void StartButton_Click(object sender, RoutedEventArgs e) 
{ 
    _searchCancellationTokenSrc = new CancellationTokenSource(); 
    CancellationToken ct = _searchCancellationTokenSrc.Token; 

    _searchTask = Task.Run(() => 
    { 
     for (int i = 0; i < 10; i++) 
     { 
      if(ct.IsCancellationRequested) 
      { 
       // Clean up here 
       ct.ThrowIfCancellationRequested(); 
      } 
      // Time consuming processing here 
      Thread.Sleep(1000); 
     } 
     return new Move(); 
    },ct); 

    _searchTask.ContinueWith((t) => 
    { 
     Console.WriteLine("Canceled"); 
    }, TaskContinuationOptions.OnlyOnCanceled); 

    _searchTask.ContinueWith((t) => 
    { 
     Console.WriteLine("Faulted. t.Exception contains details of any exceptions thrown");    
    }, TaskContinuationOptions.OnlyOnFaulted); 

    _searchTask.ContinueWith((t) => 
    {    
     Console.WriteLine("Completed t.Result contains your Move object"); 
    }, TaskContinuationOptions.OnlyOnRanToCompletion); 
} 

要取消這個,或許可以從另一個按鈕:

private void CancelButton_Click(object sender, RoutedEventArgs e) 
{ 
     _searchCancellationTokenSrc.Cancel(); 
}