在后台运行任务(PCL)

时间:2015-01-31 23:33:34

标签: c# .net task-parallel-library async-await task

我有一个async方法的课程:

public static async Task GetData() { ... }

在我使用的应用程序框架中,我需要启动该过程并在应用程序启动时忘记它:

protected override void OnStart()
{
    await MyService.GetData();
}

我无法OnStart async.如何在后台任务中启动它并忘掉它?

2 个答案:

答案 0 :(得分:4)

  

我无法制作OnStart Async。如何在后台任务中启动它   忘了吗?

为什么不呢?没有什么能阻止你做出asyncasync修饰符不会影响CLR方法签名,即您可以覆盖void方法并将其设为async

abstract class AppBase
{
    protected abstract void OnStart();
}

class App: AppBase
{
    public static async Task GetData() { await Task.Delay(1); }

    protected override async void OnStart()
    {
        await GetData(); 
    }
}

这样,至少你会在GetData投掷时看到异常,这与其他答案所暗示的不同。

确保您了解async void方法和Task错误处理的工作原理,this material可能会有所帮助。

Task.Run( () => MyService.GetData() )的其他一些问题:

  • 由于GetData 已经异步,因此用Task.Run包装它的意义不大。它通常只在客户端UI应用程序中完成,并且仅当GetData具有长时间运行的同步部分时(在它到达其第一个await之前)。否则,您也可以在没有GetData()且没有Task.Run的情况下致电await(这也是一个不好的主意:在任何一种情况下,您都会做一场大火 - 而且 - 忘记调用而不遵守可能的例外情况。)

  • Task.Run将在没有同步内容的随机池线程上启动GetData,这可能是UI应用程序或ASP.NET应用程序的问题。

答案 1 :(得分:1)

如果要触发此async操作并忘记它,您需要做的就是在不等待返回任务的情况下调用该方法:

protected override void OnStart()
{
    MyService.GetDataAsync();
}

但是,由于您没有观察到任务,因此您永远不会知道它是否成功完成。

您应该保留对任务的引用,并在以后保留await

public Task _dataTask;
protected override void OnStart()
{
    _dataTask = MyService.GetDataAsync();
}

public Task AwaitInitializationAsync()
{
    return _dataTask;
}

或添加处理任何例外的续约:

protected override void OnStart()
{
    MyService.GetDataAsync().ContinueWith(t => 
    {
        try 
        { 
            t.Wait();
        }
        catch (Exception e)
        {
            // handle exceptions
        }
    });
}

您不应该将Task.Run用作Noseratio explained,但使用async void会更加糟糕,因为async void方法中的例外情况(不是{39}} UI事件处理程序)将拆除整个过程*

您可以尝试制作方法async void,同时确保使用try-catch块不会引发任何异常:

protected override async void OnStart()
{
    try
    {
        await GetData(); 
    }
    catch (Exception e)
    {
        // handle e.
    }
}

但我仍然建议反对它,因为即使完全崩溃的可能性也很危险。


*您可以通过为AppDomain.CurrentDomain.UnhandledException注册一个偶数处理程序来解决这个问题,但这应该是最后的选择,而不是最佳实践