繁体   English   中英

在WPF中以异步登录方式设置CurrentPrincipal

[英]Set CurrentPrincipal in an asynchronous login in WPF

我一直在网上搜索此内容,但找不到真正有效的解决方案。 情况如下:我有一个WPF应用程序,我想在其中向用户显示一个简单的登录表单。 尝试使用MVVM,因此我在登录命令后有一个LoginViewModel,其中包含以下代码:

try
        {
            WithClient(servfact.GetServiceClient<IAccountService>(), proxy =>
            {
                principal = proxy.AuthenticateUser(Login, password);
            });
            Thread.CurrentPrincipal = principal;
        }
        catch(...) { ... }

“ WithClient”是我的viewmodel基类中的一种简短方法,可用于实例化和处理我的服务代理:

    protected void WithClient<T>(T proxy, Action<T> codeToExecute)
    {
        try { codeToExecute(proxy); }
        finally
        {
            IDisposable toDispose = (proxy as IDisposable);
            if(toDispose != null) { toDispose.Dispose(); }
        }
    }

现在,我的大多数服务都是异步的,并且正在进行WithClient的异步变体,它也可以正常工作:

        protected async Task WithClientAsync<T>(T proxy, Func<T, Task> codeToExecute)
    {
        try { await codeToExecute(proxy); }
        finally
        {
            IDisposable toDispose = (proxy as IDisposable);
            if(toDispose != null) { toDispose.Dispose(); }
        }
    }

每当我也想异步登录时,麻烦就开始了。 显然,我不希望UI在登录时冻结(或为此访问任何WCF服务)。 这样做本身可以很好地工作,但是问题出在我设置CurrentPrincipal的那段代码中。 这个问题可能是大多数人都熟悉的:它似乎设置得很好。 然后,在我的程序中,我想使用CurrentPrincipal(在客户端或将用户登录名发送到消息头中的WCF服务),但似乎已重置为标准GenericPrincipal。 当我将登录恢复为同步状态时,CurrentPrincipal很好。 简而言之:如何在异步代码中设置主体,让它在以后继续存在,而不是恢复为标准主体?

好吧,好吧,一年没有答案。 不用担心,因为我设法自己解决了这个问题:我只是将所有内容包裹在一个单例中:

    public sealed class CurrentPrincipalFacade : IPrincipal
{
    #region Singleton mechanism

    private static readonly CurrentPrincipalFacade instance = new CurrentPrincipalFacade();
    public static CurrentPrincipalFacade Instance { get { return instance; } }
    private CurrentPrincipalFacade() { }

    #endregion

    #region IPrincipal members

    public IPrincipal Principal { get; set; }

    public IIdentity Identity { get { return Principal == null ? null : Principal.Identity; } }

    public bool IsInRole(string role) { return Principal != null && Principal.IsInRole(role); }

    public void Reset() { Principal = new GenericPrincipal(new GenericIdentity(""), new string[] { }); }
    #endregion}

因此,我在登录后进行了设置。 我想问题是我在另一个线程中设置了主体,而当我退出该线程时却迷失了?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM