【问题标题】:Nested Asynchronous function in SilverlightSilverlight 中的嵌套异步函数
【发布时间】:2014-03-19 06:53:24
【问题描述】:

我正在尝试调用嵌套的异步函数,但没有获得所需的数据。 由于我在 Silverlight 中使用 wcf 服务,因此我只能使用异步函数。

在我的代码中,我保存了一组包含用户数据的行。在我保存之前,我需要检查用户名是唯一的。现在我只需要找出第一个,然后跳出循环并向用户显示一条消息。为了简单起见,我已经剥离了所有额外数据的功能,这就是它的外观

      private void SaveUsers(bool CloseForm)
            {
                ObservableCollection<User> _UpdatedUsers = new ObservableCollection<User>(); 
                DatabaseServiceLocal _dataService = new DatabaseServiceLocal(Database);

                foreach (UserViewModel _User in _AllUsers)
                {
                    //bool success = _dataService.IsUserNameUnique(_User.UserName, _User.UserID, Database.CurrentClient.ClientID);
                    if (_User.Dirty && !_User.IsBlank)
                    {                     
                        _dataService.CheckIsUserNameUnique += (s, e) =>
                        {
                            if (e.IsUnique)
                                _UpdatedUsers.Add(_User.SaveAsUser());
                            else
                              {
                                _UpdatedUsers = new ObservableCollection<User>();
                                csaMessageBox.Show(string.Format("Username {0} is not allowed as it already exists in the system. Please choose a different username.", ""), null);
                                return;
                              }
                        };
                        _dataService.IsUserNameUnique(_User.UserName, _User.UserID, Database.CurrentClient.ClientID);
                    }

                _dataService.UpdateStaffAndUsersCompleted += (s, e) =>
                {
                    BusyIndicator = false;
                    if (e.Success)
                    {
                        }
                        if (CloseForm)
                            ReturnToHomePage();
                        else
                        {

                            LoadUsers();
                            OnUsersSaved();
                        }
                    }

                BusyIndicator = true;
                BusyMessage = "Saving...";
                             _dataService.UpdateUsers(Database.CurrentProject.ProjectID, Database.CurrentClient.ClientID, _UpdatedUsers, _DeletedProjectUsers);
            }

在这种情况下,我试图查找用户名是否唯一,向用户显示消息并返回。 显然它不是那么简单。我尝试了几种不同的方法,但没有奏效。我如何让它工作?

【问题讨论】:

  • 如果您的用户 IsUnique,您想避免 UpdateStaffAndUsers() 调用吗?
  • 是的..如果其中一个用户不是唯一的,我不希望 UpdateStaffAndUsers() 函数运行
  • 然后放置“_dataService.UpdateUsers(Database.CurrentProject.ProjectID, Database.CurrentClient.ClientID, _UpdatedUsers, _DeletedProjectUsers);”在 CheckIsUserNameUnique 处理程序中
  • 能否请您详细说明一下。

标签: c# wcf silverlight asynchronous


【解决方案1】:

我认为您可以通过添加几个辅助函数来让您的生活更轻松。第一个是检查用户是否唯一的异步函数。如果出现错误,您可能需要添加一些代码来设置tcs.SetException

private Task<bool> IsUserUniqueAsync(UserViewModel user, DatabaseServiceLocal dataService)
{
    var tcs = new TaskCompletionSource<bool>();

    dataService.CheckIsUserNameUnique += (s, e) =>
                        {
                            tcs.SetResult(e.IsUnique);
                        };
    dataService.IsUserNameUnique(user.UserName, user.UserID, Database.CurrentClient.ClientID);
    return tcs.Task;
}

第二个异步更新所有用户

public Task<bool> UpdateUsersAsync(ObservableCollection<User> updatedUsers, DatabaseServiceLocal dataService)
{
    var tcs = new TaskCompletionSource<bool>();

    BusyIndicator = true;
    BusyMessage = "Saving...";

    dataService.UpdateStaffAndUsersCompleted += (s, e) =>
                {
                    BusyIndicator = false;
                    tcs.SetResult(e.Success);                 
                 };

    dataService.UpdateUsers(Database.CurrentProject.ProjectID, Database.CurrentClient.ClientID, updatedUsers, _DeletedProjectUsers);

    return tcs.Task;
}

那么你的SaveUsers 方法就变得简单一些了。

private async void SaveUsers(bool CloseForm)
{
    ObservableCollection<User> _UpdatedUsers = new ObservableCollection<User>(); 
    DatabaseServiceLocal _dataService = new DatabaseServiceLocal(Database);
    Dictionary<Task<bool>, User> tasks = new Dictionary<Task<bool>, User>();

    // start all tasks in parallel
    foreach (UserViewModel _User in _AllUsers)
    {
        if (_User.Dirty && !_User.IsBlank)
        { 
            tasks.Add(IsUserUniqueAsync(_User, _dataService), _User);       
        }
    }           

    // process each task as it completes
    while(tasks.Count() > 0 )
    {
        var task = await Task.WhenAny(tasks.Keys.ToArray());

        if(task.Result)
        {
            _UpdatedUsers.Add(_User.SaveAsUser()); 
        }
        else
        {
           MessageBox.Show(string.Format("Username {0} is not allowed as it already exists in the system. Please choose a different username.", ""), null);
           return;
        }

        tasks.Remove(task);
    }

    if( await UpdateUsersAsync(_UpdatedUsers, _dataService))
    {
        if (CloseForm)
            ReturnToHomePage();
        else
        {

            LoadUsers();
            OnUsersSaved();
        }
    }
}

【讨论】:

  • 我的坏...编辑了这个问题的代码并出于某种原因删除了它们。感谢您的指出。
【解决方案2】:

您的代码或多或少看起来像这样。

ObservableCollection<User> _UpdatedUsers = new ObservableCollection<User>();
int _verifiedUsersCount = 0;
DatabaseServiceLocal _dataService = new DatabaseServiceLocal(Database);

//Verify unique users
private void SaveUsers(bool CloseForm)
{

    _dataService.CheckIsUserNameUnique += CheckIsUserNameUnique;

    foreach (UserViewModel _User in _AllUsers)
    {
        //bool success = _dataService.IsUserNameUnique(_User.UserName, _User.UserID, Database.CurrentClient.ClientID);
        if (_User.Dirty && !_User.IsBlank)
        {
            _dataService.IsUserNameUnique(_User.UserName, _User.UserID, Database.CurrentClient.ClientID);
        }
    }
}

//Store verified users to save
private void CheckIsUserNameUnique(object s, CheckIsUserNameUniqueEventArgs e)
{
    if (e.IsUnique)
        _UpdatedUsers.Add(_User.SaveAsUser());
    else
    {
        csaMessageBox.Show(string.Format("Username {0} is not allowed as it already exists in the system. Please choose a different username.", ""), null);
    }
    verifiedUsersCount++;

    //Call after all the users have been verified for uniqueness
    if (_AllUsers.Count() == verifiedUsersCount)
    {
        OnUniqueUserVerifyComplete();
    }
}

//Save verified users
private void OnUniqueUserVerifyComplete()
{
    //No unique users 
    if (_UpdatedUsers.Count < 1) { return; }

    _dataService.UpdateStaffAndUsersCompleted += (s, e) =>
    {
        BusyIndicator = false;
        if (e.Success)
        {
        }
        if (CloseForm)
            ReturnToHomePage();
        else
        {
            LoadUsers();
            OnUsersSaved();
        }
    };

    BusyIndicator = true;
    BusyMessage = "Saving...";
    _dataService.UpdateUsers(Database.CurrentProject.ProjectID, Database.CurrentClient.ClientID, _UpdatedUsers, _DeletedProjectUsers);
}

【讨论】:

    猜你喜欢
    • 2012-10-12
    • 2014-10-05
    • 2019-10-02
    • 2021-02-04
    • 1970-01-01
    • 2018-10-28
    • 2014-06-23
    • 2018-04-02
    相关资源
    最近更新 更多