2015-02-23 70 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(); 
}