解析查询会将主线程停顿一分钟

时间:2014-07-08 10:55:53

标签: multithreading performance unity3d parse-platform

我使用资产商店的Parse软件包为我的Unity3D手机游戏(iOS / Android)保存用户数据。现在我遇到了一个问题,即解析查询我做了很长时间的统一主线程。我的印象是'任务' Parse的概念是为了避免这种情况,但不知何故它似乎没有效果。停止发生在编辑器中,与移动设备上的最多一分钟相比只有几秒钟。 query.FindAsync()。ContinueWith(t => {myContinuationBlock});方法立即返回,后续调用执行。 Unity3d主线程在执行查询后几秒钟停止,并在执行{myContinuationBlock}中的代码之前立即停止。

我制作了一个问题视频。在视频中你还可以看到只有Unity被停顿,底部的(原生)iAds不会受到影响:

https://www.youtube.com/watch?v=XWaCGk9Hbus(摊位是0:07 - 1:07)

这是我的查询代码(请注意,此代码运行没有问题。在ContinueWith代码执行之前发生停顿):

public static void RetrieveHighScores()
{
    DebugLog.Log ("start of RetrieveHighScores() method");
    try
    {
        ParseQuery<ParseUser> query = ParseUser.Query
        .WhereGreaterThan (_highScoreKey, 1)
        .WhereGreaterThan("updatedAt", DateTime.Now - TimeSpan.FromDays(1))
        .OrderByDescending(_score24HoursKey)
        .Limit (1000);

        DebugLog.Log ("query.FindAsync()");
        query.FindAsync().ContinueWith(t =>
        {
            try
            {
                if (t.IsFaulted || t.IsCanceled)
                {
                    DebugLog.Log("Retrieving 24 Hours High Scores Failed");
                }
                else
                {
                    DebugLog.Log("Retrieving 24 Hours High Scores successful! ");
                    IEnumerable<ParseUser> results = t.Result;
                    foreach(ParseUser user in results)
                    {
                        //doing something with user..
                    }
                    DebugLog.Log ("24 Hours High Scores processed. "+_24HourHighScoreList.Count.ToString()+" entries.");
                }
            }
            catch(System.Exception e)
            {
                DebugLog.Log("Failed to retrieve 24 Hours High Scores. Reason: " + e.Message);
            }
        });
        DebugLog.Log ("FindAsync() returned");
    }
    catch (System.Exception e)
    {
        DebugLog.Log("Failed to retrieve 24 Hours High Scores. Reason: " + e.Message);
    }

    try
    {
        ParseQuery<ParseUser>query = ParseUser.Query
        .WhereGreaterThan (_highScoreKey, 1)
        .OrderByDescending(_highScoreKey)
        .Limit (1000);

        DebugLog.Log ("query.FindAsync()");
        query.FindAsync().ContinueWith(t =>
        {
        DebugLog.Log("Retrieving Alltime High Scores successful! ");
                    IEnumerable<ParseUser> results = t.Result;
                    foreach(ParseUser user in results)
                    {
                        //doing something with user...
                    }
                    DebugLog.Log ("Alltime High Scores processed. "+_allTimeHighScoreList.Count.ToString()+" entries.");
        });
        DebugLog.Log ("FindAsync() returned");
    }
    catch (System.Exception e)
    {
        DebugLog.Log("Failed to retrieve alltime Highscores. Reason: " + e.Message);
    }
    DebugLog.Log ("end of RetrieveHighScores() method");
}

所以,我在停顿后的控制台输出中看到的下一件事是

&#34;检索Alltime High Scores成功! &#34;

现在,我知道我在这里查询1000个对象,是的,可能有更好的方法来实现高分,但我不明白为什么这个代码会阻止我的Unity3D主线程?为什么它有时会停顿一分钟,有时它根本不显眼?

这是一个严重的问题,因为我的游戏已经发布。一旦用户数据库变大,它就开始出现,现在我需要快速修复它。

如果我没有调用RetrieveHighScores()函数,那么停止不会发生,所以它必须是在解析代码从服务器接收数据并将其传递给ContinueWith代码之后发生的事情。

如果我在停止期间点击XCode中的暂停,我会看到以下内容:

Thread 1, Queue : com.apple.main-thread

#0  0x017eaeb0 in GC_mark_from ()

#1  0x017eb520 in GC_mark_some ()

#2  0x017e5d1c in GC_stopped_mark ()

#3  0x017e6228 in GC_try_to_collect_inner ()

#4  0x017e64f0 in GC_collect_or_expand ()

#5  0x017e6a38 in GC_allocobj ()

#6  0x017e957c in GC_generic_malloc_inner ()

#7  0x017e965c in GC_generic_malloc ()

#8  0x017e9920 in GC_malloc_atomic ()

#9  0x01783814 in mono_array_new_specific ()

#10 0x00c5886c in m_wrapper_managed_to_native_object___icall_wrapper_mono_array_new_specific_intptr_int at /Users/me/myproj/build/device/Libraries/mscorlib.dll.s:187982

#11 0x009ee54c in m_System_Text_RegularExpressions_Interpreter_ResetGroups at /Users/me/myproj/build/device/Libraries/System.dll.s:6462

#12 0x009eb864 in m_System_Text_RegularExpressions_Interpreter_Reset at /Users/me/myproj/build/device/Libraries/System.dll.s:5761

#13 0x009edb6c in m_157 at /Users/me/myproj/build/device/Libraries/System.dll.s:6244

#14 0x009ebc54 in m_155 at /Users/me/myproj/build/device/Libraries/System.dll.s:5813

#15 0x009eb804 in m_System_Text_RegularExpressions_Interpreter_Scan_System_Text_RegularExpressions_Regex_string_int_int at /Users/me/myproj/build/device/Libraries/System.dll.s:5745

#16 0x009f3ce8 in m_System_Text_RegularExpressions_Regex_Match_string_int at /Users/me/myproj/build/device/Libraries/System.dll.s:9106

#17 0x00370204 in m_Parse_Internal_Json_Accept_string_int_System_Text_RegularExpressions_Regex_int__System_Text_RegularExpressions_Match_ at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:3770

#18 0x0036fa80 in m_Parse_Internal_Json_ParseString_string_int_int__object_ at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:3577

#19 0x0036f56c in m_Parse_Internal_Json_ParseMember_string_int_int__object_ at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:3447

#20 0x0036f3b8 in m_Parse_Internal_Json_ParseObject_string_int_int__object_ at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:3413

#21 0x0036f99c in m_Parse_Internal_Json_ParseValue_string_int_int__object_ at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:3553

#22 0x0036f780 in m_Parse_Internal_Json_ParseArray_string_int_int__object_ at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:3500

#23 0x0036f9b8 in m_Parse_Internal_Json_ParseValue_string_int_int__object_ at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:3556

#24 0x0036f5ec in m_Parse_Internal_Json_ParseMember_string_int_int__object_ at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:3457

#25 0x0036f3b8 in m_Parse_Internal_Json_ParseObject_string_int_int__object_ at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:3413

#26 0x0036e920 in m_Parse_Internal_Json_Parse_string at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:3143

#27 0x00383168 in m_Parse_ParseClient_DeserializeJsonString_string at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:13121

#28 0x0038381c in m_Parse_ParseClient__c__DisplayClass8__RequestAsyncb__7_System_Threading_Tasks_Task_1_System_Tuple_2_System_Net_HttpStatusCode_string at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:13363

#29 0x0036de50 in m_Parse_Internal_InternalExtensions__c__DisplayClass1_2__OnSuccessb__0_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:2697

#30 0x0036e04c in m_Parse_Internal_InternalExtensions__c__DisplayClass7_1__OnSuccessb__6_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:2788

#31 0x003a3a4c in m_System_Threading_Tasks_Task__c__DisplayClass3_1__c__DisplayClass5__ContinueWithb__2 ()

#32 0x003a36b8 in m_System_Threading_Tasks_Task___cctorb__23_System_Action at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31346

#33 0x003a39bc in m_System_Threading_Tasks_Task__c__DisplayClass3_1__ContinueWithb__1_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31474

#34 0x003a4140 in m_System_Threading_Tasks_Task_1_RunContinuations at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31766

#35 0x003a4278 in m_System_Threading_Tasks_Task_1_TrySetResult_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31801

#36 0x003a4654 in m_System_Threading_Tasks_TaskCompletionSource_1_TrySetResult_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31950

#37 0x003a4fa0 in m_3d9 at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:32334

#38 0x003a44b0 in m_System_Threading_Tasks_Task_1__c__DisplayClass1__ContinueWithb__0_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31872

#39 0x003a3b3c in m_System_Threading_Tasks_Task__c__DisplayClass8__ContinueWithb__7_System_Threading_Tasks_Task ()

#40 0x00519a84 in m_System_Threading_Tasks_Task__c__DisplayClass3_1__c__DisplayClass5_int__ContinueWithb__2 ()

#41 0x003a36b8 in m_System_Threading_Tasks_Task___cctorb__23_System_Action at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31346

#42 0x004a9548 in m_1ce9 at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:165091

#43 0x003a8dcc in m_System_Threading_Tasks_Task_ContinueWith_int_System_Func_2_System_Threading_Tasks_Task_int_System_Threading_CancellationToken at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:34526

#44 0x003a321c in m_System_Threading_Tasks_Task_ContinueWith_System_Action_1_System_Threading_Tasks_Task_System_Threading_CancellationToken at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31155

#45 0x003a3168 in m_System_Threading_Tasks_Task_ContinueWith_System_Action_1_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31129

#46 0x003a3fdc in m_System_Threading_Tasks_Task_1_ContinueWith_System_Action_1_System_Threading_Tasks_Task_1_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31721

#47 0x003a4ed4 in m_3d8 at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:32304

#48 0x003a44b0 in m_System_Threading_Tasks_Task_1__c__DisplayClass1__ContinueWithb__0_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31872

#49 0x003a3b3c in m_System_Threading_Tasks_Task__c__DisplayClass8__ContinueWithb__7_System_Threading_Tasks_Task ()

#50 0x00519a84 in m_System_Threading_Tasks_Task__c__DisplayClass3_1__c__DisplayClass5_int__ContinueWithb__2 ()

#51 0x003a36b8 in m_System_Threading_Tasks_Task___cctorb__23_System_Action at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31346

#52 0x004a9548 in m_1ce9 at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:165091

#53 0x003a4140 in m_System_Threading_Tasks_Task_1_RunContinuations at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31766

#54 0x003a4278 in m_System_Threading_Tasks_Task_1_TrySetResult_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31801

#55 0x003a4654 in m_System_Threading_Tasks_TaskCompletionSource_1_TrySetResult_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31950

#56 0x003a3a60 in m_System_Threading_Tasks_Task__c__DisplayClass3_1__c__DisplayClass5__ContinueWithb__2 at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31498

#57 0x003a36b8 in m_System_Threading_Tasks_Task___cctorb__23_System_Action at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31346

#58 0x003a39bc in m_System_Threading_Tasks_Task__c__DisplayClass3_1__ContinueWithb__1_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31474

#59 0x003a4140 in m_System_Threading_Tasks_Task_1_RunContinuations at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31766

#60 0x003a4278 in m_System_Threading_Tasks_Task_1_TrySetResult_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31801

#61 0x003a4654 in m_System_Threading_Tasks_TaskCompletionSource_1_TrySetResult_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31950

#62 0x003a4fa0 in m_3d9 at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:32334

#63 0x003a44b0 in m_System_Threading_Tasks_Task_1__c__DisplayClass1__ContinueWithb__0_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31872

#64 0x003a3b3c in m_System_Threading_Tasks_Task__c__DisplayClass8__ContinueWithb__7_System_Threading_Tasks_Task ()

#65 0x00519a84 in m_System_Threading_Tasks_Task__c__DisplayClass3_1__c__DisplayClass5_int__ContinueWithb__2 ()

#66 0x003a36b8 in m_System_Threading_Tasks_Task___cctorb__23_System_Action at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31346

#67 0x004a9548 in m_1ce9 at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:165091

#68 0x003a8dcc in m_System_Threading_Tasks_Task_ContinueWith_int_System_Func_2_System_Threading_Tasks_Task_int_System_Threading_CancellationToken at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:34526

#69 0x003a321c in m_System_Threading_Tasks_Task_ContinueWith_System_Action_1_System_Threading_Tasks_Task_System_Threading_CancellationToken at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31155

#70 0x003a3168 in m_System_Threading_Tasks_Task_ContinueWith_System_Action_1_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31129

#71 0x003a3fdc in m_System_Threading_Tasks_Task_1_ContinueWith_System_Action_1_System_Threading_Tasks_Task_1_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31721

#72 0x003a4ed4 in m_3d8 at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:32304

#73 0x003a44b0 in m_System_Threading_Tasks_Task_1__c__DisplayClass1__ContinueWithb__0_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31872

#74 0x003a3b3c in m_System_Threading_Tasks_Task__c__DisplayClass8__ContinueWithb__7_System_Threading_Tasks_Task ()

#75 0x00519a84 in m_System_Threading_Tasks_Task__c__DisplayClass3_1__c__DisplayClass5_int__ContinueWithb__2 ()

#76 0x003a36b8 in m_System_Threading_Tasks_Task___cctorb__23_System_Action at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31346

#77 0x004a9548 in m_1ce9 at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:165091

#78 0x003a4140 in m_System_Threading_Tasks_Task_1_RunContinuations at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31766

#79 0x003a4278 in m_System_Threading_Tasks_Task_1_TrySetResult_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31801

#80 0x003a4654 in m_System_Threading_Tasks_TaskCompletionSource_1_TrySetResult_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31950

#81 0x003a3a60 in m_System_Threading_Tasks_Task__c__DisplayClass3_1__c__DisplayClass5__ContinueWithb__2 at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31498

#82 0x003a36b8 in m_System_Threading_Tasks_Task___cctorb__23_System_Action at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31346

#83 0x003a39bc in m_System_Threading_Tasks_Task__c__DisplayClass3_1__ContinueWithb__1_System_Threading_Tasks_Task at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31474

#84 0x003a4140 in m_System_Threading_Tasks_Task_1_RunContinuations at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31766

#85 0x003a4278 in m_System_Threading_Tasks_Task_1_TrySetResult_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31801

#86 0x003a4654 in m_System_Threading_Tasks_TaskCompletionSource_1_TrySetResult_T at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:31950

#87 0x003a0848 in m_Parse_PlatformHooks__c__DisplayClass2f__c__DisplayClass35__RequestAsyncb__2a_UnityEngine_WWW at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:29764

#88 0x003a0334 in m_Parse_PlatformHooks__c__DisplayClass20__RegisterNetworkRequestb__1f at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:29572

#89 0x003a0dbc in m_Parse_PlatformHooks__RunDispatcherd__39_MoveNext at /Users/me/myproj/build/device/Libraries/Parse.Unity.dll.s:29915

#90 0x0126ecec in scripting_method_invoke(ScriptingMethod*, MonoObject*, ScriptingArguments&, MonoException**) at /Applications/buildAgent/work/d63dfc6385190b60/Runtime/Scripting/Backend/Mono/ScriptingBackendApi_Mono.cpp:196

#91 0x01309390 in ScriptingInvocation::Invoke(MonoException**, bool) at /Applications/buildAgent/work/d63dfc6385190b60/Runtime/Scripting/Backend/ScriptingInvocation.cpp:128

#92 0x0130935c in ScriptingInvocation::Invoke(MonoException**) at /Applications/buildAgent/work/d63dfc6385190b60/Runtime/Scripting/Backend/ScriptingInvocation.cpp:113

#93 0x01309308 in bool ScriptingInvocation::Invoke<bool>(MonoException**) at /Applications/buildAgent/work/d63dfc6385190b60/Runtime/Scripting/Backend/ScriptingInvocation.cpp:80

#94 0x012df7e4 in Coroutine::InvokeMoveNext(MonoException**) at /Applications/buildAgent/work/d63dfc6385190b60/Runtime/Mono/Coroutine.cpp:196

#95 0x012df57c in Coroutine::Run() at /Applications/buildAgent/work/d63dfc6385190b60/Runtime/Mono/Coroutine.cpp:221

#96 0x012df544 in Coroutine::ContinueCoroutine(Object*, void*) at /Applications/buildAgent/work/d63dfc6385190b60/Runtime/Mono/Coroutine.cpp:78

#97 0x012593c4 in DelayedCallManager::Update(int) at /Applications/buildAgent/work/d63dfc6385190b60/Runtime/GameCode/CallDelayed.cpp:164

#98 0x012d0630 in PlayerLoop(bool, bool, IHookEvent*) at /Applications/buildAgent/work/d63dfc6385190b60/Runtime/Misc/Player.cpp:1880

#99 0x01117878 in UnityPlayerLoop at /Applications/buildAgent/work/d63dfc6385190b60/PlatformDependent/iPhonePlayer/LibEntryPoint.mm:241

#100    0x00d2ff34 in -[UnityAppController(Rendering) repaint] at /Users/me/myproj/build/device/Classes/UnityAppController+Rendering.mm:55

似乎解析的JSON解析在mainthread上运行,但为什么呢? 这里发生了什么,我怎么能避免让主线变得迟钝?

//注意:偶尔会发生停顿(查询成功) - 好像Parse有时会成功地在另一个线程上进行解析,但大部分时间都是在主线程上进行解析。

1 个答案:

答案 0 :(得分:-1)

我建议如果你将Unity探查器连接到你的设备,你会发现你的Linq查询正在创建大量的垃圾 - 而且你的设备上的垃圾收集会阻碍你的主线程

以艰难的方式重新实现您的排行榜功能,不要使用Linq。 Linq为程序员节省了时间 - 而不是机器,不要在游戏中使用它。