我想等待Task <T>完成一些特殊规则:如果在X毫秒后它还没有完成,我想向用户显示一条消息.如果它在Y毫秒后没有完成,我想自动请求取消.
我可以使用Task.ContinueWith异步等待任务完成(即安排在任务完成时执行的操作),但这不允许指定超时.我可以使用Task.Wait同步等待任务完成超时,但这会阻止我的线程.如何异步等待任务完成超时?
在一个线程中,我创建一些System.Threading.Task并启动每个任务.
当我做一个.Abort()杀死线程时,任务不会中止.
我怎样才能传递.Abort()给我的任务?
好的,我的问题非常简单.为什么这段代码不会抛出TaskCancelledException?
static void Main()
{
var v = Task.Run(() =>
{
Thread.Sleep(1000);
return 10;
}, new CancellationTokenSource(500).Token).Result;
Console.WriteLine(v); // this outputs 10 - instead of throwing error.
Console.Read();
}
Run Code Online (Sandbox Code Playgroud)
但这一个有效
static void Main()
{
var v = Task.Run(() =>
{
Thread.Sleep(1000);
return 10;
}, new CancellationToken(true).Token).Result;
Console.WriteLine(v); // this one throws
Console.Read();
}
Run Code Online (Sandbox Code Playgroud) .net c# task-parallel-library cancellationtokensource cancellation-token
在我的应用程序中,我正在创建一些并发的Web请求,并且我对其中任何一个请求完成都感到满意,因此我使用的是Task.WhenAny:
var urls = new string[] {
"https://stackoverflow.com",
"https://superuser.com",
"https://www.reddit.com/r/chess",
};
var tasks = urls.Select(async url =>
{
using (var webClient = new WebClient())
{
return (Url: url, Data: await webClient.DownloadStringTaskAsync(url));
}
}).ToArray();
var firstTask = await Task.WhenAny(tasks);
Console.WriteLine($"First Completed Url: {firstTask.Result.Url}");
Console.WriteLine($"Data: {firstTask.Result.Data.Length:#,0} chars");
Run Code Online (Sandbox Code Playgroud)
首次完成的网址:https
://superuser.com数据:121.954个字符
我不喜欢这种实现方式,因为未完成的任务会继续下载不再需要的数据,并且浪费带宽,我希望为下一批请求保留这些带宽。因此,我正在考虑取消其他任务,但是我不确定该怎么做。我发现了如何使用CancellationToken取消特定的Web请求:
public static async Task<(string Url, string Data)> DownloadUrl(
string url, CancellationToken cancellationToken)
{
try
{
using (var webClient = new WebClient())
{
cancellationToken.Register(webClient.CancelAsync);
return (url, await webClient.DownloadStringTaskAsync(url)); …Run Code Online (Sandbox Code Playgroud) 如果需要超过2分钟,我需要取消UpdateDatabase()函数.我已经尝试过canceltokens和计时器,但我无法解决这个问题(找不到任何合适的例子).
你能帮帮我吗?
App.xaml.cs
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
await PerformDataFetch();
}
internal async Task PerformDataFetch()
{
await LocalStorage.UpdateDatabase();
}
Run Code Online (Sandbox Code Playgroud)
LocalStorage.cs
public async static Task<bool> UpdateDatabase()
{
await ..// DOWNLOAD FILES
await ..// CHECK FILES
await ..// RUN CONTROLES
}
Run Code Online (Sandbox Code Playgroud)
根据答案编辑我的课程.
App.xaml.cs保持不变.编辑UpdateDatabase()并在LocalStorage.cs中添加新方法RunUpdate():
public static async Task UpdateDatabase()
{
CancellationTokenSource source = new CancellationTokenSource();
source.CancelAfter(TimeSpan.FromSeconds(30)); // how much time has the update process
Task<int> task = Task.Run(() => RunUpdate(source.Token), …Run Code Online (Sandbox Code Playgroud) 我有一个带有async处理程序的按钮,该处理程序在异步方法上调用awaits。看起来是这样的:
private async void Button1_OnClick(object sender, RoutedEventArgs e)
{
await IpChangedReactor.UpdateIps();
}
Run Code Online (Sandbox Code Playgroud)
这里是如何IpChangedReactor.UpdateIps()的外观:
public async Task UpdateIps()
{
await UpdateCurrentIp();
await UpdateUserIps();
}
Run Code Online (Sandbox Code Playgroud)
一直到异步。
现在,我有一个在其tick事件中DispatcherTimer反复调用的await IpChangedReactor.UpdateIps。
假设我点击了按钮。现在事件处理程序正在等待UpdateIps并返回到调用方,这意味着WPF将继续执行其他操作。同时,如果计时器触发,它将再次调用UpdateIps,现在这两种方法将同时运行。因此,我看到的方式类似于使用2个线程。比赛条件会发生吗?(我的一部分人说不,因为它们都在同一线程中运行。但是这很令人困惑)
我知道异步方法不一定在单独的线程上运行。但是,在这种情况下,这非常令人困惑。
如果我在这里使用同步方法,它将按预期工作。计时器滴答事件将仅在第一个呼叫完成后运行。
有人可以启发我吗?
我正在使用具有async方法但不是CancellationToken重载的外部库.
现在我正在使用另一个StackOverflow问题的扩展方法来添加CancellationToken:
public async static Task HandleCancellation(this Task asyncTask, CancellationToken cancellationToken)
{
// Create another task that completes as soon as cancellation is requested. http://stackoverflow.com/a/18672893/1149773
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
cancellationToken.Register(() =>
tcs.TrySetCanceled(), useSynchronizationContext: false);
Task cancellationTask = tcs.Task;
// Create a task that completes when either the async operation completes, or
// cancellation is requested.
Task readyTask = await Task.WhenAny(asyncTask, cancellationTask);
// In case of cancellation, register a continuation to observe any unhandled …Run Code Online (Sandbox Code Playgroud) 我的应用程序当前使用一些命令执行 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(); …Run Code Online (Sandbox Code Playgroud) 在我的 Windows Store 应用程序中,我有一个方法
public async static Task InitAds()
{
Debug.WriteLine("API: Loading Ad images");
await Task.WhenAll(ads.Select(l => l.Value).Where(l=>l!=null).Select(l => l.StartRotation()));
}
Run Code Online (Sandbox Code Playgroud)
我用来下载和初始化(下载,解析|项目中的广告。调用时等待此方法
...
await AdReader.InitAds()
...
Run Code Online (Sandbox Code Playgroud)
问题是广告服务器有时响应非常缓慢。我想要一个超时时间,比如说这个方法运行 10 秒。如果它没有在这个超时时间内完成,我希望它被杀死并且我的代码继续。
实现这一点的最佳方法是什么?我找到了如何在等待中取消任务?但它使用 TaskFactory 并且当我尝试这种方法并在 Task.Run 中调用我的方法时,它不会等待并且代码继续。
编辑:
StartRotation 也是一个异步方法调用另一个异步方法
public async Task StartRotation(CancellationToken ct)
{
if (Images.Count == 1)
{
await Image.LoadAndSaveImage(ct);
}
if (Images.Count <2) return;
foreach (var img in Images)
{
await img.LoadAndSaveImage(ct);
}
Delay = Image.Delay;
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = TimeSpan.FromMilliseconds(Delay);
dt.Tick += (s, …Run Code Online (Sandbox Code Playgroud) c# ×9
.net ×5
async-await ×4
abort ×1
c#-5.0 ×1
cancellation ×1
task ×1
timeout ×1
windows ×1
winrt-async ×1
wpf ×1