none
C# Async遇到的死锁(deadlock)问题

    问题

  • 我在Winform的demo中学习使用Async时候遇到的死锁问题!

    简述:

    通过IProgress更新进度条,都是Async的方法,Task.WhenAll或者await一个进度条的task到达100%,开始第二个进度条更新

    代码如下,共两个cs

    第一个cs:

     class ProgressHelper
        {
            public int PercentCompleted = 0;
            public int MaxValue = 100;
    
            private IProgress<int> m_progress = new Progress<int>();
    
            public IProgress<int> Progress
            {
                get { return m_progress = new Progress<int>(); }
                set { m_progress =  value; }
            }
    
    
            public async Task<string> ProgressReportAsync(int scaleValue, string returnResult)
            {
                PercentCompleted = 0;
    
                while (PercentCompleted <= MaxValue)
                {
                    if (m_progress != null)
                    {
                        await Task.Delay(TimeSpan.FromMilliseconds(50));
    
                        if (PercentCompleted + scaleValue <= 100)
                        {
                            PercentCompleted += scaleValue;
                        }
                        else
                        {
                            PercentCompleted += 100 - PercentCompleted;
                        }
    
                        m_progress.Report(PercentCompleted);
                    }
                }
                return returnResult;
            }
        }

    第二个cs:

    private async void StartRunButton_Click(object sender, EventArgs e) { RunProgressBar().ConfigureAwait(false); } private async Task RunProgressBar() { Task<string> task = RunProgressBar(m_firstProgressBar, m_firstProgressValueLabel, 7, "Process One Done!"); task.ConfigureAwait(false); await Task.WhenAll(task);

    //无法运行到下面 RunProgressBar(m_lastProgressBar, null, 7, "Process Last Done!"); } private async Task<string> RunProgressBar(ProgressBar progressBar, Label progressBarValueLable, int scaleValue, string returnResult) { if (progressBar.Value != 0) { progressBar.Value = 0; } ProgressHelper progressHelper = new ProgressHelper(); (progressHelper.Progress as Progress<int>).ProgressChanged += (sender, e) => { if (progressHelper.PercentCompleted <= progressHelper.MaxValue) { if (progressBarValueLable != null) { progressBarValueLable.Text = string.Format("{0}%", progressHelper.PercentCompleted); } if (progressBar != null) { progressBar.Value = progressHelper.PercentCompleted; } } }; return await progressHelper.ProgressReportAsync(scaleValue, returnResult); }


    2016年11月16日 16:36

答案

  •  while (PercentCompleted <= MaxValue)

    这一行导致一个精度条死循环了,无法结束, PercentCompleted最大100 永远满足<=100.

    修改成 

     while (PercentCompleted < MaxValue)

    Bob Bao

    Do you still use the same Windows 8 LockScreen always? Download Chameleon Win8 App quickly, that changes your LockScreen constantly.
    你是否还在看着一成不变的Windows 8锁屏而烦恼,赶紧下载这个 百变锁屏 应用,让你的锁屏不断地变化起来。

    • 已建议为答案 Bob_Bao 2016年11月17日 3:31
    • 已标记为答案 Eden(Peng)Pan 2016年11月17日 8:32
    2016年11月17日 3:30
  • Hi 蜗牛...金鱼,

    我的测试结果是和Bob_Bao一样的,以下是我的截图。

    你的代码在VS中有许多蓝色的波浪线,你需要在前面加await。

    如下:

     private async Task RunProgressBar()
            {
                Task<string> task = RunProgressBar(progressBar1,
                        label1, 7,
                        "Process One Done!");
    
                await task.ConfigureAwait(false);
                await Task.WhenAll(task);
    
    
                //无法运行到下面
                await RunProgressBar(progressBar2, null, 7, "Process Last Done!");
    
    
    
    
            }

    Best Regards,

    Hart

    如果你的问题已经被解决,请记得标记有用的回复,作为答案


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    2016年11月17日 6:01
    版主

全部回复

  •  while (PercentCompleted <= MaxValue)

    这一行导致一个精度条死循环了,无法结束, PercentCompleted最大100 永远满足<=100.

    修改成 

     while (PercentCompleted < MaxValue)

    Bob Bao

    Do you still use the same Windows 8 LockScreen always? Download Chameleon Win8 App quickly, that changes your LockScreen constantly.
    你是否还在看着一成不变的Windows 8锁屏而烦恼,赶紧下载这个 百变锁屏 应用,让你的锁屏不断地变化起来。

    • 已建议为答案 Bob_Bao 2016年11月17日 3:31
    • 已标记为答案 Eden(Peng)Pan 2016年11月17日 8:32
    2016年11月17日 3:30
  • Hi 蜗牛...金鱼,

    我的测试结果是和Bob_Bao一样的,以下是我的截图。

    你的代码在VS中有许多蓝色的波浪线,你需要在前面加await。

    如下:

     private async Task RunProgressBar()
            {
                Task<string> task = RunProgressBar(progressBar1,
                        label1, 7,
                        "Process One Done!");
    
                await task.ConfigureAwait(false);
                await Task.WhenAll(task);
    
    
                //无法运行到下面
                await RunProgressBar(progressBar2, null, 7, "Process Last Done!");
    
    
    
    
            }

    Best Regards,

    Hart

    如果你的问题已经被解决,请记得标记有用的回复,作为答案


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    2016年11月17日 6:01
    版主
  • Thank u very much,困惑我好几天了
    2016年11月17日 8:31
  • Thank u very much,困惑我好几天了
    2016年11月17日 8:32
  • Hi 蜗牛...金鱼,

    感谢你回来标记帖子,有什么问题,请随时在这儿问,我们将第一时间帮助你.

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2016年11月17日 8:35
    版主