C#定时函数

C#定时函数,c#,wpf,multithreading,asynchronous,timer,C#,Wpf,Multithreading,Asynchronous,Timer,我有以下问题: 我需要运行一个函数搜索(depth x),它基本上搜索决策树直到某个深度,然后返回(或留在类成员中)Move类型的值。同时,如果搜索持续时间过长,我希望能够“取消”搜索的执行 同样重要的是,如果搜索完成得更快,我不必等待。我意识到这并不复杂,但我对C#并发控制并不十分熟悉。这里有一个简单的示例作为起点: public class Runner { private Task<int> search(CancellationToken ct) {

我有以下问题:

我需要运行一个函数搜索(depth x),它基本上搜索决策树直到某个深度,然后返回(或留在类成员中)Move类型的值。同时,如果搜索持续时间过长,我希望能够“取消”搜索的执行


同样重要的是,如果搜索完成得更快,我不必等待。我意识到这并不复杂,但我对C#并发控制并不十分熟悉。

这里有一个简单的示例作为起点:

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);
    }
}

为此,我将使用
任务
,因为它内置了在任务完成时处理错误、取消和运行
继续任务
的机制

假设您在问题中暗示了一种自定义返回类型的移动:

private Task<Move> _searchTask;
private CancellationTokenSource _searchCancellationTokenSrc;

到目前为止,您已经尝试过的代码是…?目前我的代码没有定时器,我不知道如何修改它,使其具有提前终止的选项。您能与我们共享您的代码吗?
backgroundworker
任务
异步实现都支持取消(虽然采用了不同的方法,一种是通过
bool
,另一种是通过
token
)。我建议使用
Task
,因为这是一种较新的方法。为什么要进行否决?这是一个关于定时c#函数的小例子。
private Task<Move> _searchTask;
private CancellationTokenSource _searchCancellationTokenSrc;
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();
 }