c# - 向 ObservableCollection 添加元素会导致异常 Index was out of range

标签 c# xamarin collections observablecollection indexoutofrangeexception

我有一个代码允许用户选择一个文件,将一些关于它的信息添加到一个可观察的集合并显示上传进度,完成后,它将图像绑定(bind)到 ImageView 。它立即正常工作,但如果您重复该过程,则会抛出异常:

System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
  at at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.43(intptr,intptr)
  at at (wrapper native-to-managed) Android.Runtime.DynamicMethodNameCounter.43(intptr,intptr)

插入新元素并获取其索引的代码

switch(x){

 // some code...

    case 6:

        // .... some code 


            _ = Task.Run(async () => {
            try
            {
                int i = default;

            Msg newmsg2 = new Msg() { UploadProgress = 0.0, UploadProgressVisibility = true, IsImageSend = true, ImageSend = "@drawable/icon_default" };

            valuesLock.EnterWriteLock();
            try
            {
                // THE ISSUE IS RELATED WITH THIS WORK
                Device.BeginInvokeOnMainThread(() => ListaMsg.Add(newmsg2));
            }
            finally
            {
                valuesLock.ExitWriteLock();
                valuesLock.EnterReadLock();
                try
                {
                    // THE ISSUE IS RELATED WITH THIS WORK

                    i = ListaMsg.IndexOf(newmsg2); 

                    // Some data can be added while the progress is being updated, I need to get the index of this exactly Item, can't get it with Count-1

                }
                finally
                {
                    valuesLock.ExitReadLock();
                    Resultado a = await Task.Run(()=>UploadFile(filename, i));
                    if (a.status == "ok")
                    {
                        valuesLock.EnterWriteLock();
                        try
                        {
                            Device.BeginInvokeOnMainThread(() =>
                            {
                                MyList[i].msg = "Image was sent";
                                MyList[i].status = true;
                                MyList[i].ImageSend = "mydomain/assets/libs/thumb.php?h=150&w=150&img=" + a.msg;
                            });
                        }
                        finally
                        {
                            valuesLock.ExitWriteLock();
                            SendMsg(6, a.msg, i);
                        }
                    }
                    else
                    {
                        valuesLock.EnterWriteLock();
                        try
                        {
                            Device.BeginInvokeOnMainThread(() =>
                            {
                                MyList[i].ImageSend = "@drawable/icon_default";
                                MyList[i].icon = "\uf057";
                                MyList[i].IconColor = Xamarin.Forms.Color.Red;
                            });
                        }
                        finally { valuesLock.ExitWriteLock(); }
                    }
                }
            }
        }
        catch (Exception e)
        {
            ...
        }
    });
break;
}

上传方法

public async Task<Resultado> UploadFile(string url, string filepath)
{
  //some code

  webclient.UploadProgressChanged += new UploadProgressChangedEventHandler(UploadProgressCallback);

  //some code
}

最后是 ProgressChanged 回调:

private void UploadProgressCallback(object sender, UploadProgressChangedEventArgs e, int idreference)
{
    double temp = ((double)e.BytesSent) / filesize;
    Device.BeginInvokeOnMainThread(() => {
        valuesLock.EnterWriteLock();
        try
        {
            // THE EXCEPTION IS BEING THREW AT LINE BELOW, idreference value is -1 and not the correct index
            MyList[idreference].UploadProgress = temp;
        }
        finally { valuesLock.ExitWriteLock(); }
    });
}

为什么这只一次有效?是我漏掉了还是做错了什么?

最佳答案

问题的根源在于包含 IndexOf() 方法的部分。它在主线程上执行之前执行,索引始终为 -1。通过更改修复:

Device.BeginInvokeOnMainThread(() => ... );

通过

await Device.InvokeOnMainThreadAsync(() => { ... } );

关于c# - 向 ObservableCollection 添加元素会导致异常 Index was out of range,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61554098/

相关文章:

JavaScript:为什么 &lt;input type ="image"> 元素不出现在 document.forms.elements 中?

c# - VB 中的 DLL 函数签名

c# - 类型 'Attribute' 在未引用的程序集中定义 - Xamarin

php - 将数据从集合回显到 Blade View

c# - 如何将值/参数传递到 "public delegate void"中?

c# - 启动画面 Activity 强制我的设备重新启动

java - hashmap如何确保每个哈希值在哈希表中分配唯一的索引

c# - 使用 EndOfStream 和检查 null 有什么区别?

c# - 首次登录后如何强制更改密码

c# - 检查数组中一行数据的最简单且可能最有效的方法