相关疑难解决方法(0)

异步等待Task <T>以超时完成

我想等待Task <T>完成一些特殊规则:如果在X毫秒后它还没有完成,我想向用户显示一条消息.如果它在Y毫秒后没有完成,我想自动请求取消.

我可以使用Task.ContinueWith异步等待任务完成(即安排在任务完成时执行的操作),但这不允许指定超时.我可以使用Task.Wait同步等待任务完成超时,但这会阻止我的线程.如何异步等待任务完成超时?

.net c# task-parallel-library

350
推荐指数
13
解决办法
20万
查看次数

如何中止/取消TPL任务?

在一个线程中,我创建一些System.Threading.Task并启动每个任务.

当我做一个.Abort()杀死线程时,任务不会中止.

我怎样才能传递.Abort()给我的任务?

.net c# multithreading task abort

144
推荐指数
7
解决办法
15万
查看次数

在Task.Run中使用CancellationToken超时不起作用

好的,我的问题非常简单.为什么这段代码不会抛出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

32
推荐指数
4
解决办法
4万
查看次数

Task.WhenAny取消未完成的任务并超时

在我的应用程序中,我正在创建一些并发的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)

.net c# task-parallel-library async-await

8
推荐指数
1
解决办法
421
查看次数

使用超时取消静态异步功能

如果需要超过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)

c# c#-5.0 microsoft-metro windows-runtime winrt-async

7
推荐指数
1
解决办法
1610
查看次数

重入异步/等待?

我有一个带有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个线程。比赛条件会发生吗?(我的一部分人说不,因为它们都在同一线程中运行。但是这很令人困惑)

我知道异步方法不一定在单独的线程上运行。但是,在这种情况下,这非常令人困惑。

如果我在这里使用同步方法,它将按预期工作。计时器滴答事件将仅在第一个呼叫完成后运行。

有人可以启发我吗?

.net c# wpf multithreading async-await

5
推荐指数
1
解决办法
1860
查看次数

在没有CancellationToken的情况下停止任务

我正在使用具有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)

c# cancellation async-await

5
推荐指数
1
解决办法
4478
查看次数

异步任务超时

我的应用程序当前使用一些命令执行 Adob​​e Illustrator。当结果文件出现在某个确切的文件夹中(具有异步功能)时等待,并在文件准备好时对文件执行某些操作。

但问题是,有时 Adob​​e Illustrator 会失败并且应用程序一直等待。在这种情况下,我不知道如何应用超时机制来终止 Adob​​e 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)

c# windows timeout

5
推荐指数
2
解决办法
1万
查看次数

一段时间后如何取消异步任务

在我的 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# async-await microsoft-metro windows-runtime

2
推荐指数
1
解决办法
5234
查看次数