2017-01-26 20 views
0

私は以下のクラスがあります。/非同期の流れと混同待つ機能

DataAccessFactory:

public class DataAccessFactory 
{ 
    public static IUserAccessLayer User() => new UserAccessLayer(new DataContext()); 
    public static IAuthenticationAccessLayer Authentication() => new AuthenticationAccessLayer(new DataAccess.DataContext()); 
} 

AuthenticationAccessLayer:

public class AuthenticationAccessLayer : IAuthenticationAccessLayer 
{ 
    private readonly DataContext context; 

    public AuthenticationAccessLayer(DataContext context) 
    { 
     this.context = context; 
    } 

    public async void RegisterAsync(UserRegisterModel model) 
    { 
     context.User.Add(new UserModel() 
     { 
      EmailAddress = model.Email, 
      PasswordHash = model.PasswordHash, 
      PasswordSalt = model.PasswordSalt 
     }); 
    } 

    public async Task<bool> EmailExist(string email) 
    { 
     var user = await context.User.Where(x => x.EmailAddress.Equals(email)).FirstOrDefaultAsync(); 
     if (user == null) 
      return false; 
     else 
      return true; 
    } 
} 

USERSTORE:

public class UserStore : ViewModelBase 
{ 
    public UserStore() 
    { 
    } 

    public UserStore(int userID) 
    { 
     this.UserID = userID; 
    } 

    #region Authentication 

    public async Task<bool> AuthenticateAsync(LoginModel model) 
    { 
     return await DataAccessFactory.Authentication().LoginAsync(model); 
    } 

    public async void RegisterUserAsync(UserRegisterModel model) 
    { 
     var store = DataAccessFactory.Authentication(); 

     //check if unique email 
     if(await store.EmailExist(model.Email)) 
      throw new ValidationException($"Email {model.Email} is already registered."); 

     store.RegisterAsync(model); 
    } 

    #endregion 

} 

をマイ質問は、ユーザーストアは関数で、EmailExist関数が例外を返すか、例外をスローする前に、UserRegisterModelがDBに追加されますか?

+1

'AuthenticationAccessLayer.RegisterAsync'は実際には' async'ではありません。 'context.User.Add'は返されず、' Task'が返ってくることもありません。 –

+0

[非同期voidメソッドを避ける](http://haacked.com/archive/2014/11/11/async -void-methods /) – stuartd

答えて

2

いいえ、RegisterExserAsyncメソッドは、EmailExistメソッドが返された後に実行されます。

msdn

のawait演算子を待つタスクが完了するまでメソッドの実行をサスペンド に非同期方式でタスクに適用されます。 タスクは進行中の作業を表します。
...
await式は、 が実行されているスレッドをブロックしません。かわりに、コンパイラは、待機するタスクの続行として 非同期メソッドの残りの部分を登録します。制御すると、 はasyncメソッドの呼び出し元に戻ります。タスクが完了すると、 は継続を呼び出し、asyncメソッドの実行は中止した を再開します。

+0

私はそれを得ると思います。 awaitの後のメソッドの実行は中断されますが、スレッドはUI固有のものなど他のスレッドを自由に実行できます。 EmailExistが値を返すまで待ってから実行されませんか? –

-1

おそらくスレッドスケジューラに依存します。あなたは

public async Task RegisterUserAsync(UserRegisterModel model) 
    { 
     var store = DataAccessFactory.Authentication(); 

     //check if unique email 
     if(await store.EmailExist(model.Email)) 
      throw new ValidationException($"Email {model.Email} is already registered."); 

     await store.RegisterAsync(model); 
    } 

のようなものであることをRegisterUserAsyncを定義した場合しかし、その後RegisterAsyncEmailExist後に実行されます。

+1

メソッド*が* async voidの場合でも、 'RegisterExync'は' EmailExist'が終了する前に実行できません。 'RegisterUserAsync'はそれが終わる前に単に戻ってくるだけで、終わったときに知っている方法を呼んでくれません。 – Servy

0

EmailExistの機能を待機しているので、電子メールが存在する場合は、ValidateExceptionが送信されます(これは、タスクの戻り値のタイプとawaitキーワードに注意してください)。