XamarinのAndroidアプリに問題がありますが、問題をAzure Mobileクライアントに絞り込んだと思います。 。ネット。私はコンソールアプリケーションで自分の問題を再現しようとしました。タスクと並行してAzureモバイルクライアントを呼び出す問題.WhenAll
私の目標は、複数のapi呼び出しを並行して行うことです。以下の例では、データベースに存在するユーザーを取得するために繰り返し呼び出しを行います。各呼び出し(GetUsersBメソッド)がすべて正常に実行されるのを待つとき、私はTask.WhenAll(GetUsersAメソッド)を待つことを試みるときにほとんど例外が発生します。
class Program
{
static void Main(string[] args)
{
var service = new MyService();
try
{
//GetUsersA(service).Wait(); //Often throws the exception attached but ocasionally is successful
GetUsersB(service).Wait(); //Never throws an exception
}
catch (AggregateException e)
{
foreach (var ex in e.InnerExceptions)
{
Console.WriteLine(e.InnerException.Message);
Console.WriteLine(e.InnerException.StackTrace);
}
}
Console.WriteLine("main done");
Console.ReadLine();
}
public async static Task GetUsersA(MyService service)
{
await Task.WhenAll(service.GetUser("d48977fce3c6fc6b5a74c"),
service.GetUser("d48977fce3c6fc6b5a74c"),
service.GetUser("d48977fce3c6fc6b5a74c"),
service.GetUser("d48977fce3c6fc6b5a74c"),
service.GetUser("d48977fce3c6fc6b5a74c"),
service.GetUser("d48977fce3c6fc6b5a74c"));
Console.WriteLine("tasks complete");
}
public async static Task GetUsersB(MyService service)
{
await service.GetUser("d48977fce3c6fc6b5a74c");
await service.GetUser("d48977fce3c6fc6b5a74c");
await service.GetUser("d48977fce3c6fc6b5a74c");
await service.GetUser("d48977fce3c6fc6b5a74c");
await service.GetUser("d48977fce3c6fc6b5a74c");
Console.WriteLine("tasks complete");
}
}
ここで、必要な場合には、たMyServiceクラスここ
public class MyService
{
private MobileServiceClient azClient;
public MyService()
{
azClient = new MobileServiceClient("https://mysite.azurewebsites.net/");
}
public async Task<User> GetUser(string id)
{
return await azClient.GetTable<User>().LookupAsync(id);
}
}
である内部例外の出力です:
Collection was modified; enumeration operation may not execute.
at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Enumerator.MoveNext()
at Microsoft.WindowsAzure.MobileServices.MobileServiceContractResolver.CreateProperties(Type type, MemberSerialization memberSerialization)
at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateObjectContract(Type objectType)
at Microsoft.WindowsAzure.MobileServices.MobileServiceContractResolver.CreateObjectContract(Type type)
at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract(Type objectType)
at Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract(Type type)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)
at Newtonsoft.Json.Linq.JToken.ToObject[T](JsonSerializer jsonSerializer)
at Microsoft.WindowsAzure.MobileServices.MobileServiceSerializer.<>c__DisplayClass35_0`1.<Deserialize>b__0()
at Microsoft.WindowsAzure.MobileServices.MobileServiceSerializer.TransformSerializationException[T](Action action, JToken token)
at Microsoft.WindowsAzure.MobileServices.MobileServiceSerializer.Deserialize[T](JToken json, JsonSerializer jsonSerializer)
at Microsoft.WindowsAzure.MobileServices.MobileServiceSerializer.Deserialize[T](JToken json)
at Microsoft.WindowsAzure.MobileServices.MobileServiceTable`1.<LookupAsync>d__14.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.WindowsAzure.MobileServices.MobileServiceTable`1.<LookupAsync>d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at TaskTest.MyService.<GetUser>d__2.MoveNext() in C:\Users\jalley\Documents\Visual Studio 2015\Projects\TaskTest\TaskTest\MyService.cs:line 24
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at TaskTest.Program.<GetUsersA>d__1.MoveNext() in C:\Users\jalley\Documents\Visual Studio 2015\Projects\TaskTest\TaskTest\Program.cs:line 31
このリンクを確認してください.http://stackoverflow.com/questions/23621285/proper-use-of-task-whenall – Prashant
@Prashantこれは彼の質問とは関係ありません。 –
デッドロックが発生する可能性があるため、Task.Wait()を使用しないでください。 awaitまたはWhenAllを使用します。 –