C#定时函数
C# Timed function
我有以下问题:
我需要 运行 一个函数搜索(深度 x),它基本上搜索决策树直到一定深度,然后 returns(或留在 class 成员中)a移动类型的值。同时,如果搜索持续时间过长,我希望能够 "cancel" 执行搜索。
同样重要的是,如果搜索完成得更快,我就不必等待它。我意识到这并不复杂,但我并不真正熟悉 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);
}
}
您可以像这样在控制台应用程序中使用它:
Console.WriteLine("test");
var r = new Runner();
r.SearchAsync().Wait();
r.SearchAsync().Wait();
r.SearchAsync().Wait();
r.SearchAsync().Wait();
Console.WriteLine("done..");
我会为此使用 Task
,因为它内置了处理错误、取消和 运行 Continuation Tasks
任务完成时的机制。
假设我认为您在问题中暗示了自定义 return 类型的移动:
private Task<Move> _searchTask;
private CancellationTokenSource _searchCancellationTokenSrc;
然后单击按钮或类似按钮,开始您的任务。这将立即 return,保持你的 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();
}
我有以下问题:
我需要 运行 一个函数搜索(深度 x),它基本上搜索决策树直到一定深度,然后 returns(或留在 class 成员中)a移动类型的值。同时,如果搜索持续时间过长,我希望能够 "cancel" 执行搜索。
同样重要的是,如果搜索完成得更快,我就不必等待它。我意识到这并不复杂,但我并不真正熟悉 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);
}
}
您可以像这样在控制台应用程序中使用它:
Console.WriteLine("test");
var r = new Runner();
r.SearchAsync().Wait();
r.SearchAsync().Wait();
r.SearchAsync().Wait();
r.SearchAsync().Wait();
Console.WriteLine("done..");
我会为此使用 Task
,因为它内置了处理错误、取消和 运行 Continuation Tasks
任务完成时的机制。
假设我认为您在问题中暗示了自定义 return 类型的移动:
private Task<Move> _searchTask;
private CancellationTokenSource _searchCancellationTokenSrc;
然后单击按钮或类似按钮,开始您的任务。这将立即 return,保持你的 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();
}