首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在WinForms-Validating Event中同步异步任务

在WinForms-Validating Event中同步异步任务
EN

Stack Overflow用户
提问于 2020-08-06 15:35:08
回答 1查看 228关注 0票数 1

我有一个经典的WinForms应用程序,它与服务器应用程序接口进行异步通信。这是通过异步等待模式实现的。

现在我遇到了一个关于“验证”事件的问题。我们使用此事件进行客户端验证(检查输入是否为空)并设置cancel。如果输入有效,则将输入发送到服务器异步并等待结果。

这就是我的问题。现在,控件表示它是有效的。当回调将cancel事件设置为false时,为时已晚。

下面是我的代码:

代码语言:javascript
复制
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    public string CustomerName { get; set; }

    private async void Button1_Validating(object sender, CancelEventArgs e)
    {
        if (CustomerName == null)
        {
            e.Cancel = true;
        }
        else
        {
            var isValidAndSaved = await SaveOnServerAsync(CustomerName);

            // Here is the Problem: Setting e.Cancel in callback is too late.
            if (isValidAndSaved)
            {
                e.Cancel = false;
            }
            else
            {
                e.Cancel = true;
            }
        }
    }

    /// <returns>True if the given model was valid and save operation was successfull.</returns>
    public async Task<bool> SaveOnServerAsync(string customerName)
    {
        await Task.Delay(3000); // Send given customerName to server in real app.
        return customerName.Contains("%") ? false : true;
    }
}

在这种情况下,我尝试了经典的编程(synchron),在主线程中‘等待’taks。但是后来我产生了一个死锁。

代码语言:javascript
复制
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

        public string CustomerName { get; set; } = "3";

    private void Button1_Validating(object sender, CancelEventArgs e)
    {
        if (CustomerName == null)
        {
            e.Cancel = true;
        }
        else
        {
            // Deadlock because MainThread waits for callback. 
            var isValidAndSaved = SaveOnServerAsync(CustomerName).Result;
            if (isValidAndSaved)
            {
                e.Cancel = false;
            }
            else
            {
                e.Cancel = true;
            }
        }
    }

    /// <returns>True if the given model was valid and save operation was successfull.</returns>
    public async Task<bool> SaveOnServerAsync(string customerName)
    {
        await Task.Delay(3000); // Send given customerName to server in real app.
        return customerName.Contains("%") ? false : true;
    }
}

有没有人想出一个好的模式?

如果我在等待异步任务之前将Cancel设置为false,那么我的问题将是用户单击被丢弃,并且用户体验是足够的。

EN

回答 1

Stack Overflow用户

发布于 2020-08-11 14:57:09

我找到了一个可行的方法。除第一个任务外,所有其他任务都需要"ConfigureAwait(false)".请参见方法'SaveOnServerAsync'.

代码语言:javascript
复制
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public string CustomerName { get; set; } = "3";

        private void Button1_Validating(object sender, CancelEventArgs e)
        {
            if (CustomerName == null)
            {
                e.Cancel = true;
            }
            else
            {
                var isValidAndSaved = SaveOnServerAsync(CustomerName).Result;
                if (isValidAndSaved)
                {
                    e.Cancel = false;
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }

        /// <returns>True if the given model was valid and save operation was successfull.</returns>
        public async Task<bool> SaveOnServerAsync(string customerName)
        {
            await Task.Delay(3000)
                // The solution is that all deeper Tasks need line below.
                .ConfigureAwait(false);
            ;
            return customerName.Contains("%") ? false : true;
        }
    }

我找到了很多关于这个问题的文章。这听起来有点误导了她的概念。

这篇MS文章的图3解释了死锁情况:https://docs.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming

这里解释了避免死锁的解决方案:https://docs.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming#configure-context

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63278874

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档