Closed angelru closed 3 years ago
I have discovered that it has to do with this line, any solution? var user = await Search (message.FromId);
Do you mean it works well without that line? What is the code of Search
?
@f-miyu https://forums.xamarin.com/discussion/184438/system-argumentexception-handle-must-be-valid
08-20 12:31:42.660 E/mono (24148): Unhandled Exception:
08-20 12:31:42.660 E/mono (24148): System.ArgumentException: Handle must be valid.
08-20 12:31:42.660 E/mono (24148): Parameter name: instance
08-20 12:31:42.660 E/mono (24148): at Java.Interop.JniEnvironment+InstanceMethods.CallBooleanMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method) [0x00009] in <42748fcc36b74733af2d9940a8f3cc8e>:0
08-20 12:31:42.660 E/mono (24148): at Android.Runtime.JNIEnv.CallBooleanMethod (System.IntPtr jobject, System.IntPtr jmethod) [0x0000e] in <227a96d68a0440cea172be41b1306654>:0
08-20 12:31:42.660 E/mono (24148): at Java.Util.IIteratorInvoker.get_HasNext () [0x00033] in <227a96d68a0440cea172be41b1306654>:0
08-20 12:31:42.660 E/mono (24148): at System.Linq.Extensions+<ToEnumerator_Dispose>d__5`1[T].MoveNext () [0x00063] in <227a96d68a0440cea172be41b1306654>:0
08-20 12:31:42.660 E/mono (24148): at System.Linq.Enumerable+SelectIListIterator`2[TSource,TResult].MoveNext () [0x00029] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Linq/src/System/Linq/Select.cs:487
08-20 12:31:42.660 E/mono (24148): at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_1 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1037
08-20 12:31:42.660 E/mono (24148): at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) [0x0000d] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/threadpool.cs:1370
08-20 12:31:42.660 E/mono (24148): at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00071] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:968
08-20 12:31:42.660 E/mono (24148): at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:910
08-20 12:31:42.660 E/mono (24148): at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () [0x00021] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/threadpool.cs:1341
08-20 12:31:42.660 E/mono (24148): at System.Threading.ThreadPoolWorkQueue.Dispatch () [0x00074] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/threadpool.cs:899
08-20 12:31:42.660 E/mono (24148): at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/threadpool.cs:1261
08-20 12:31:42.662 E/mono-rt (24148): [ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentException: Handle must be valid.
08-20 12:31:42.662 E/mono-rt (24148): Parameter name: instance
08-20 12:31:42.662 E/mono-rt (24148): at Java.Interop.JniEnvironment+InstanceMethods.CallBooleanMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method) [0x00009] in <42748fcc36b74733af2d9940a8f3cc8e>:0
08-20 12:31:42.662 E/mono-rt (24148): at Android.Runtime.JNIEnv.CallBooleanMethod (System.IntPtr jobject, System.IntPtr jmethod) [0x0000e] in <227a96d68a0440cea172be41b1306654>:0
08-20 12:31:42.662 E/mono-rt (24148): at Java.Util.IIteratorInvoker.get_HasNext () [0x00033] in <227a96d68a0440cea172be41b1306654>:0
08-20 12:31:42.662 E/mono-rt (24148): at System.Linq.Extensions+<ToEnumerator_Dispose>d__5`1[T].MoveNext () [0x00063] in <227a96d68a0440cea172be41b1306654>:0
08-20 12:31:42.662 E/mono-rt (24148): at System.Linq.Enumerable+SelectIListIterator`2[TSource,TResult].MoveNext () [0x00029] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.Linq/src/System/Linq/Select.cs:487
08-20 12:31:42.662 E/mono-rt (24148): at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_1 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1037
08-20 12:31:42.662 E/mono-rt (24148): at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) [0x0000d] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/threadpool.cs:1370
08-20 12:31:42.662 E/mono-rt (24148): at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00071] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:968
08-20 12:31:42.662 E/mono-rt (24148): at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/executioncontext.cs:910
08-20 12:31:42.662 E/mono-rt (24148): at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () [0x00021] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/threadpool.cs:1341
08-20 12:31:42.662 E/mono-rt (24148): at System.Threading.ThreadPoolWorkQueue.Dispatch () [0x00074] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/threadpool.cs:899
08-20 12:31:42.662 E/mono-rt (24148): at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/threading/threadpool.cs:1261
private async Task<string> Search(string id)
{
var user = await FirebaseService.UserAsync(id);
users.Add(id, user.Name);
return user.Name;
}
yes it works fine without that line
How is AddSnapshotListener
called? Please provide this code in detail.
private IQuerySnapshot querySnapshot;
CrossCloudFirestore.Current.Instance.GetCollection(Collection)
.AddSnapshotListener((snapshot, error) =>
{
querySnapshot = snapshot;
QuerySnapshot();
});
private async void QuerySnapshot()
if (querySnapshot != null)
{
lastVisibleDocument = querySnapshot.Documents.LastOrDefault();
foreach (var documentChange in querySnapshot.DocumentChanges)
{
Message message;
switch (documentChange.Type)
{
case DocumentChangeType.Added:
message = documentChange.Document.ToObject<Message>();
var user = await Search(message.FromId);
message.FromName = user;
List.Add(message);
break;
case DocumentChangeType.Modified:
break;
case DocumentChangeType.Removed:
break;
}
}
}
}
private async Task<string> Search(string id)
{
var user = await FirebaseService.UserAsync(id);
users.Add(id, user.Name);
return user.Name;
}
do I do something wrong? could it be a xamarin or c# thing? I have to say that the exception only happens sometimes, I think it may be memory issues one way to reproduce it is to enter and exit many times on the page, where the code is.
Try the following.
CrossCloudFirestore.Current.Instance.GetCollection(Collection)
.AddSnapshotListener((snapshot, error) =>
{
QuerySnapshot(snapshot);
});
private async void QuerySnapshot(IQuerySnapshot querySnapshot)
if (querySnapshot != null)
{
lastVisibleDocument = querySnapshot.Documents.LastOrDefault();
foreach (var documentChange in querySnapshot.DocumentChanges)
{
Message message;
switch (documentChange.Type)
{
case DocumentChangeType.Added:
message = documentChange.Document.ToObject<Message>();
var user = await Search(message.FromId);
message.FromName = user;
List.Add(message);
break;
case DocumentChangeType.Modified:
break;
case DocumentChangeType.Removed:
break;
}
}
}
}
@f-miyu the same thing keeps happening, I do not understand why
08-20 12:31:42.662 E/mono-rt (24148): at System.Linq.Extensions+<ToEnumerator_Dispose>d__5
1[T].MoveNext () [0x00063] in <227a96d68a0440cea172be41b1306654>:0 `
will it have something to do with it?
How about this?
private async void QuerySnapshot(IQuerySnapshot querySnapshot)
{
if (querySnapshot != null)
{
lastVisibleDocument = querySnapshot.Documents.LastOrDefault();
var messages = await Task.WhenAll(
querySnapshot.DocumentChanges
.Where(change => change.Type == DocumentChangeType.Added)
.Select(async change =>
{
var message = change.Document.ToObject<Message>();
var user = await Search(message.FromId);
message.FromName = user.Name;
return message;
}));
List.AddRange(messages);
}
}
@f-miyu It seems that it works well, although I will do more tests, this exception occurred because the task was not completed well? or because the ienumerable is not async? as can be done in c # 8.0 https://docs.microsoft.com/en-us/archive/msdn-magazine/2019/november/csharp-iterating-with-async-enumerables-in-csharp-8, when i test further i will put a comment.
I'm not sure, but I think the cause is data race. Therefore, all DocumentChanges
data are accessed synchronously.
thanks!
@f-miyu I have detected that within the AddSnapshotListener event I cannot check if an element exists within a list, for example:
private readonly Dictionary<string, string> users = new Dictionary<string, string>();
chatMessagesListener = CrossCloudFirestore.Current.Instance.GetCollection(Settings.ChatMessagesCollection)
.GetDocument(_chatRoom.ChatId)
.GetCollection(Settings.MessagesCollection)
.OrderBy(Settings.CreatedAt, false)
.AddSnapshotListener((snapshot, error) =>
{
QuerySnapshot(snapshot);
});
private async void QuerySnapshot(IQuerySnapshot querySnapshot)
{
if (snapshot!= null)
{
lastVisibleDocument = snapshot.Documents.LastOrDefault();
var messages = await Task.WhenAll(
querySnapshot.DocumentChanges
.Where(change => change.Type == DocumentChangeType.Added)
.Select(async change =>
{
var message = change.Document.ToObject<Message>();
var user = await Search(message.FromId);
message.FromName = user.Name;
return message;
}));
List.AddRange(messages);
}
}
private async Task<string> Search(string id)
{
string name;
if (users.ContainsKey(id))
{
name = users[id];
}
else
{
var user = await FirebaseService.UserAsync(id);
users.Add(id, user.Name);
name = user.Name;
}
return name;
}
in the search method it always goes to the else then the exception is thrown because the added id exists
You should use ConcurrentDictionary
for thread-safe.
private readonly ConcurrentDictionary<string, Task<string>> users = new ConcurrentDictionary<string, Task<string>>();
private Task<string> Search(string id)
{
return users.GetOrAdd(id, async id =>
{
var user = await FirebaseService.UserAsync(id);
return user.Name;
});
}
This is fantastic, I didn't know it, thank you very much for everything and especially for this great library :)
Code:
Line 126 foreach (var documentChange in querySnapshot.DocumentChanges)