2016-07-02 5 views
1

Xamarin 응용 프로그램에서 영역을 사용하고 있으며 원격 소스를 기반으로 로컬 데이터베이스를 새로 고치는 데 문제가 있습니다. 원격 엔드 포인트에서 데이터를 가져 와서 Realm을 사용하여 로컬에 저장하면 더 쉽고 빠르게 액세스 할 수 있습니다.영역 쓰기 대기 완료

  1. 것이 가능한 경우 원격 소스로부터 데이터를 가져 다음과 같이

    프로그램 흐름이다.

  2. 지금까지 본 ID를 추적하면서 원격 소스에서 반환 한 엔티티를 반복합니다. 새 엔티티 또는 업데이트 된 엔티티가 영역에 기록됩니다. 로컬에 저장된 개체의 집합을 통해
  3. 루프 (트랜잭션에) 우리가 Realm.Remove(entity);와 2 단계에서 보지 못한 요소를 제거
  4. 돌아 불행하게도, 실체는 전에 4 단계에서 반환 된 Realm.All<Entity>();

모든 "삭제"작업이 작성되었습니다. 결과적으로 로컬 데이터베이스가 완전히 동기화되기 전에 몇 가지 새로 고침이 필요합니다.

foreach (Entity entity in realm.All<Entity>()) 
{ 
    if (seenIds.Contains(entity.Id)) 
    { 
     continue; 
    } 

    realm.Write(() => { 
     realm.Remove(entity); 
    }); 
} 

는 트랜잭션이 Realm.All<Entity>();을 반환하기 전에 완료 될 때까지 영역 대기를하는 방법이 다음과 같이

제거 작업이 이루어집니다?

+0

당신이 나를 보여줄 수 있습니까? – jzeferino

+0

물론 첫 번째 글에 추가했습니다. – vicdelfant

답변

0

저는 이것이 특히 렘 문제는 아니라고 확신합니다. 동일한 패턴은 많은 열거 가능하고 변경 가능한 컨테이너에서 문제를 일으킬 것입니다. 목록을 반복하는 동안 목록에서 항목을 제거하므로 열거 형이 너무 멀리 이동하고 있습니다. 영역 거래에 버퍼링이 없습니다

그래서 나는 그것이 입니다 보장하지에 대한 거래까지 영역 대기가을 완료되었지만 목록 논리입니다 있습니다.

다르게이 작업을 수행하는 두 가지 기본 방법이 있습니다

  1. 사용 ToListAll에서 모든 개체의 목록을 얻을 -이 많은 객체 경우 모든 개체를 인스턴스화하기 때문에 비싸다는.
  2. 루프 내에서 개체를 제거하는 대신 제거 할 항목 에 추가하십시오. 그런 다음 해당 목록을 반복하십시오.

여기서 Write으로 수행하는 것처럼 제거 당 트랜잭션을 사용하는 것은 상대적으로 느립니다. 하나의 트랜잭션으로 많은 작업을 수행 할 수 있습니다.

우리는 또한보다 효율적인 처리 방법을 제공 할 수있는 영역 API에 대한 다른 개선 작업을 수행 중입니다. 상대적 데이터 크기 (루프의 레코드 수와 삭제 레코드 수)를 아는 것은 매우 유용합니다. 우리 샘플 데이터와 스키마 ([email protected]로 개인적으로 보낼 수 있음)를 얻는 것을 좋아합니다.

옵션 2의 예 : your'e가 삭제 트랜잭션을 수행하는 방법을

var toDelete = new List<Entity>(); 
foreach (Entity entity in realm.All<Entity>()) 
{ 
    if (!seenIds.Contains(entity.Id)) 
     toDelete.Add(entity); 
} 
realm.Write(() => { 
    foreach (Entity entity in toDelete)) 
     realm.Remove(entity); 
}); 
+1

감사합니다. 당신은 완전히 옳았습니다.이 문제는 정말로 foreach 내의 realm.Remove()에 의해 야기되었으며 정말로 Realm과 관련이 없습니다. 가끔 쉬운 일은 간과하기 쉽습니다. 참조 용으로 전자 메일로 데이터 세트 샘플을 보내 드리겠습니다. – vicdelfant