最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】C#程序运行过程中出错:Value of xxx is not valid for Value, Value should be between minimum and maximum, System.Exception, System.ArgumentOutOfRangeException

C# crifan 4070浏览 0评论

【问题】

之前写的一个小程序:

downloadSonstasteMusic(下载Songtaste歌曲) v1.5 – 下载Songtaste(ST)中正在播放的歌曲/单首歌曲/整张专辑

用于下载songtaste中的歌曲;

在下载一个160多M的歌曲期间,会不断地更新UI中的progressbar。

在下载过程中:

downloding some

出错:

:{"Value of ‘-12’ is not valid for ‘Value’. ‘Value’ should be between ‘minimum’ and ‘maximum’.\r\nParameter name: Value"} System.Exception {System.ArgumentOutOfRangeException}

截图:

Value of is not valid for Value Value should be between minimum and maximum

详细信息:

-   ex	{"Value of '-12' is not valid for 'Value'. 'Value' should be between 'minimum' and 'maximum'.\r\nParameter name: Value"}	System.Exception {System.ArgumentOutOfRangeException}
+   [System.ArgumentOutOfRangeException]	{"Value of '-12' is not valid for 'Value'. 'Value' should be between 'minimum' and 'maximum'.\r\nParameter name: Value"}	System.ArgumentOutOfRangeException
    _className	null	string
+   _data	{System.Collections.ListDictionaryInternal}	System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
    _dynamicMethods	null	object
+   _exceptionMethod	{Void set_Value(Int32)}	System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
    _exceptionMethodString	null	string
    _helpURL	null	string
    _HResult	-2146233086	int
+   _innerException	null	System.Exception
    _message	"Value of '-12' is not valid for 'Value'. 'Value' should be between 'minimum' and 'maximum'."	string
    _remoteStackIndex	0	int
    _remoteStackTraceString	null	string
    _source	"System.Windows.Forms"	string
+   _stackTrace	{sbyte[192]}	object {sbyte[]}
    _stackTraceString	null	string
    _xcode	-532459699	int
+   _xptrs	0	System.IntPtr
+   Data	{System.Collections.ListDictionaryInternal}	System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
    HelpLink	null	string
    HResult	-2146233086	int
+   InnerException	null	System.Exception
    IsTransient	false	bool
    Message	"Value of '-12' is not valid for 'Value'. 'Value' should be between 'minimum' and 'maximum'.\r\nParameter name: Value"	string
    Source	"System.Windows.Forms"	string
    StackTrace	"   at System.Windows.Forms.ProgressBar.set_Value(Int32 value)\r\n   at downloadSongtasteMusic.frmDownloadSongtasteMusic.increaseDownloadProgressBar(Object sender, EventArgs e) in D:\\tmp\\tmp_dev_root\\downloadSongtasteMusic\\downloadSongtasteMusic\\downloadSongtasteMusic\\frmDownloadSongtasteMusic.cs:line 82\r\n   at System.Windows.Forms.Timer.OnTick(EventArgs e)\r\n   at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)\r\n   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)\r\n   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)\r\n   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)\r\n   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)\r\n   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)\r\n   at System.Windows.Forms.Application.DoEvents()\r\n   at crifanLib.getUrlRespStreamBytes(Byte[]& respBytesBuf, String url, Dictionary`2 headerDict, Dictionary`2 postDict, Int32 timeout) in D:\\tmp\\tmp_dev_root\\downloadSongtasteMusic\\downloadSongtasteMusic\\downloadSongtasteMusic\\crifanLib.cs:line 1286"	string
+   TargetSite	{Void set_Value(Int32)}	System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
+   Static members		

 

【解决过程】

1.本来是以为下载方面的函数出错的,结果现在看起来,就像是,progressbar中的错误。

估计是哪里错误了,把-12当做当前的progress了,所以出现这个错误。

2.尝试去把:

System.Windows.Forms.Application.DoEvents();

去掉:

        try
        {
            //HttpWebResponse resp = getUrlResponse(url, headerDict, postDict, timeout);
            HttpWebResponse resp = getUrlResponse(url, headerDict, postDict);
            int expectReadoutLen = (int)resp.ContentLength;

            totalLength = expectReadoutLen;
            currentLength = 0;

            Stream binStream = resp.GetResponseStream();
            //int streamDataLen  = (int)binStream.Length; // erro: not support seek operation

            do
            {
                //let up layer update its UI, otherwise up layer UI will no response during this func exec time
                //try not to update ui see whether still error
                //System.Windows.Forms.Application.DoEvents();
                
                // here download logic is:
                // once request, return some data
                // request multiple time, until no more data
                curReadoutLen = binStream.Read(respBytesBuf, curBufPos, expectReadoutLen);
                if (curReadoutLen > 0)
                {
                    curBufPos += curReadoutLen;

                    currentLength = curBufPos;

                    expectReadoutLen = expectReadoutLen - curReadoutLen;

                    realReadoutLen += curReadoutLen;
                }
            } while (curReadoutLen > 0);
        }
        catch(Exception ex)
        {
            realReadoutLen = -1;
            MessageBox.Show(ex.Data.ToString());
        }

看看结果如何。

结果果然是,去除了progressbar的更新,结果就可以正常下载整首歌曲了:

no progressbar can download well

所以,现在已证实,就是使用:

System.Windows.Forms.Application.DoEvents();

然后在下载歌曲期间,更新UI中的progressbar,而导致此问题的。

3.但是此处问题是,偶尔会发生此问题,不知道何种原因导致的。

4.也去确认了一下,progressbar的属性设置,都是OK的:

progressbar property is ok

minimum是0,maximum是100.

5.又去看了代码,貌似就是下面代码:

        //method 1: use timer
        private void increaseDownloadProgressBar(object sender, EventArgs e)
        {
            // Increment the value of the ProgressBar a value of one each time.
            int currentPecent = getDownloadPercent();

            //pgbDownload.Increment(1);
            //pgbDownload.Increment(currentPecent);
            pgbDownload.Value = currentPecent;
            
            // Determine if we have completed
            if (pgbDownload.Value >= pgbDownload.Maximum)
            {
                // Stop the timer.
                downloadTimer.Stop();

                pgbDownload.Value = 0;
            }
        }

中的

pgbDownload.Value = currentPecent;

偶发错误,导致currentPecent为-12的。

所以,加上调试代码,去看看何时,何种情况,会导致出现负数。

果然调试找到了错误时候的情况:

found error negative percent

然后手动去计算一下:

curPercent

= (currentLength * 100) / totalLength;

= 21475282 * 100 / 165230759;

= 12.99714540438563

-> 应该是等于12的,不知道为何系统异常,变成-12 了。

很是诡异。

6.后来终于搞懂了,原来是:

上面的:

21475282 * 100 = 2147528200

该值,已经超过了

2^31=2147483648

不过,当然是小于:

2^32=4294967296

的。

所以,此处,超过2^13的话,就表示是负数了。

所以,此处相关代码,从int改为long:

    private long totalLength = 0;
    private long currentLength = 0;

    //return current download percentage (max=100)
    public int getCurDownloadPercent()
    {
        int curPercent = 0;
        if ((currentLength > 0) && (totalLength > 0))
        {
            //NOTE: here currentLength * 100 maybe exceed 2^31=2147483648, so here must use long, can NOT use int
            //otherwise it will becomd nagative value
            curPercent = (int)((currentLength * 100) / totalLength);
        }
                
        return (int)curPercent;
    }

然后再去运行,最后就可以一直正常的下载,正常的更新UI中的进度条了:

can update ui normally

 

【总结】

所以,结果就是:

代码中更新progressbar时,由于错误的负数-12,赋值给progressbar导致progressbar出错。

而此负数的值,是由于不小心用了int,而currentLength * 100超过了2^31,变成了负数所导致的;

所以解决办法就是:

确保赋值给progressbar的值:

pgbDownload.Value = currentPecent;

是正数。此处把对应变量从int改为long,确保计算出来的currentPecent不会为负数,就可以了。

 

教训:

永远都不要轻视,代码中,可能出现的任何异常情况;

即使想不到,其实也应该在代码中,体现变量的特性。

而此处即:

其实最好的办法,是使用unit之类的,以便保证计算出来的百分比,不会是负数;

只是还是觉得很多地方都要用到强制转换,所以才懒得去改了。

转载请注明:在路上 » 【已解决】C#程序运行过程中出错:Value of xxx is not valid for Value, Value should be between minimum and maximum, System.Exception, System.ArgumentOutOfRangeException

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.171 seconds, using 22.15MB memory