将元素添加到ObservableCollection会导致异常索引超出范围 [英] Adding elements to ObservableCollection causes exception Index was out of range

查看:145
本文介绍了将元素添加到ObservableCollection会导致异常索引超出范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个代码,允许用户选择一个文件,将有关该文件的一些信息添加到一个可观察的集合中,并显示上传进度,完成后,它将图像绑定到Image视图.它可以立即正常工作,但是如果您重复此过程,则会引发异常:

I have a code that allows the user pick a file, adds some info about it to an observable collection and shows the upload progress, when finished, it binds the image to an Image view. It works properly at once but if you repeat the process, an exception is threw:

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(); }
    });
}

为什么这一次只能起作用?我想念还是做错了什么?

Why this works only at once? Did I miss or did something wrong?

推荐答案

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

The root of problem was the part that contains IndexOf() method. It was executing before the ancedent execution on Main Thread and index was always -1. Fixed by changing:

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

作者

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

这篇关于将元素添加到ObservableCollection会导致异常索引超出范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆