Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重写方法并添加async关键字是否安全_C#_Asynchronous_Xamarin_Xamarin.android_Async Await - Fatal编程技术网

C# 重写方法并添加async关键字是否安全

C# 重写方法并添加async关键字是否安全,c#,asynchronous,xamarin,xamarin.android,async-await,C#,Asynchronous,Xamarin,Xamarin.android,Async Await,考虑到异步和同步代码的明显混合,我想知道下面使用async await是否安全 您有一个派生类,它重写一个虚拟方法,并将async关键字添加到方法签名中,以声明它将执行异步操作 public class BaseClass { public virtual void Foo() { Bar(); // note: there is no await on this call, yet Bar is async in derived class }

考虑到异步和同步代码的明显混合,我想知道下面使用async await是否安全

您有一个派生类,它重写一个虚拟方法,并将async关键字添加到方法签名中,以声明它将执行异步操作

public class BaseClass
{
    public virtual void Foo()
    {
        Bar(); // note: there is no await on this call, yet Bar is async in derived class
    }

    protected virtual void Bar()
    {
        Console.WriteLine("Base.Bar");
    }
}

// Derived class has implementation for Bar() which is asynchronous
// is that a problem? The compiler builds this, should we be worried about async and sync being mixed?
//
public class DerivedClass : BaseClass
{
    protected override async void Bar()
    {
        Console.WriteLine("Derived.Bar");
        await Task.Delay(1000);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var derived = new DerivedClass();
        derived.Foo(); // note: there is no await on this call, yet Foo becomes async when it calls Bar which is async.
    }
}
注意在这个例子中,Foo是如何调用Bar的,在这个例子中,Bar是派生的和异步的,但是Foo并不等待调用。如果它愿意,它不能,在基类上,Bar的签名是同步的

public class BaseClass
{
    public virtual void Foo()
    {
        Bar(); // note: there is no await on this call, yet Bar is async in derived class
    }

    protected virtual void Bar()
    {
        Console.WriteLine("Base.Bar");
    }
}

// Derived class has implementation for Bar() which is asynchronous
// is that a problem? The compiler builds this, should we be worried about async and sync being mixed?
//
public class DerivedClass : BaseClass
{
    protected override async void Bar()
    {
        Console.WriteLine("Derived.Bar");
        await Task.Delay(1000);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var derived = new DerivedClass();
        derived.Foo(); // note: there is no await on this call, yet Foo becomes async when it calls Bar which is async.
    }
}

我提出这个问题的原因是,在Android上的Xamarin中,当您希望在活动启动时执行异步代码时,建议覆盖OnStart并添加async关键字。但是基本活动类上的方法不是异步的。

主要问题是它是
async void
,而不是
async Task
。这通常不是你想要的。你不能等待它,它的异常会得到不同的处理。参见。1)是的,您可以将
async
添加到
OnStart
void override方法中,该关键字标记编译器转换,以将代码作为状态机实现。2)
Xamarin在Android上建议覆盖OnStart并添加async
该建议来自何处(?),因为这实际上取决于您在
OnStart
中等待的任务之前和之后所做的工作,这可能是个问题,查阅活动生命周期以了解方法流。实际上,该语言支持async void,这是否是一个好主意取决于具体情况,事件处理程序是async void。问题不在于返回类型,也不在于异常处理。这只是一种方式,很明显,异步是一种附加功能,在最初设计C#时从未考虑过。不能将虚拟基方法声明为async并确保派生方法也是async。同一事件的故事。你别无选择。OnStart()通常非常麻烦,但也没什么好担心的,因为你希望你的应用程序在它终止时能保留一段时间而不会可怕地死掉,但异步代码还没有完成。仅供参考:
Activity.OnStart
不是Android活动上下文中的事件处理程序(因此
Xamarin.Android
)。它是生命周期方法链和基于Android的API的一部分,因此除非Xamarin决定将
async
自动生成到所有生成的C#/JNI/Java包装器代码中(当然是一个糟糕的选择),您可以&需要将
async
应用于被覆盖的基于void的Android活动生命周期方法,以
等待其中的任务(除非创建任务并以fire/forget模式调用Start适合您需要执行的代码)。