我的应用程序当前使用某些命令执行Adobe Illustrator。等待结果文件出现在某个确切的文件夹中(使用异步功能),并在文件准备就绪时执行某些操作。
但问题是,有时Adobe Illustrator失败,应用程序一直在等待。在这种情况下,我无法弄清楚,如何应用超时机制来杀死Adobe Illustrator并跳过当前进程。
以下是代码:
...
await WhenFileCreated(result_file_name);
if (File.Exists(result_file_name))
{
...
public static Task WhenFileCreated(string path)
{
if (File.Exists(path))
return Task.FromResult(true);
var tcs = new TaskCompletionSource<bool>();
FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(path));
FileSystemEventHandler createdHandler = null;
RenamedEventHandler renamedHandler = null;
createdHandler = (s, e) =>
{
if (e.Name == Path.GetFileName(path))
{
tcs.TrySetResult(true);
watcher.Created -= createdHandler;
watcher.Dispose();
}
};
renamedHandler = (s, e) =>
{
if (e.Name == Path.GetFileName(path))
{
tcs.TrySetResult(true);
watcher.Renamed -= renamedHandler;
watcher.Dispose();
}
};
watcher.Created += createdHandler;
watcher.Renamed += renamedHandler;
watcher.EnableRaisingEvents = true;
return tcs.Task;
}
如何对此应用超时?有什么建议吗?
答案 0 :(得分:0)
尝试修改代码以设置此超时,例如。
var tcs = new TaskCompletionSource<TestResult>();
const int timeoutMs = 20000;
var ct = new CancellationTokenSource(timeoutMs);
ct.Token.Register(() => tcs.TrySetCanceled(), useSynchronizationContext: false);
您可以在以下网站找到更多详情: Timeout an async method implemented with TaskCompletionSource
答案 1 :(得分:0)
最简单的方法是针对实际任务竞赛Task.Delay
:
await Task.WhenAny(WhenFileCreated(result_file_name),
Task.Delay(TimeSpan.FromSeconds(5));
更好的方法是在异步方法中实现取消
public static Task WhenFileCreated(string path,
CancellationToken ct =
default(CancellationToken))
{
//...
var tcs = new TaskCompletionSource<bool>();
ct.Register(() => tcs.TrySetCanceled())
//...
}
...然后传入cancellation token with a timeout:
using(var cts = new CancellationTokenSource(5000))
{
try
{
await WhenFileCreated(string path, cts.Token);
}
catch(TaskCanceledException)
{
//...
}
}