2016-03-28 31 views
1

Lazerli kaynakları (örneğin bir veritabanından veya bir ağ üzerinden) alabilen bir işçi sınıfı oluşturmak ve daha sonra UI'de sıfır gecikme gösterimi için bunları hazırlamak istiyorum. Bu işçi sınıfı kullanıcı arabirimine veya kullanıcı arabirimine bağlı olmamalıdır, yani herhangi bir yerde çalışabilmelidir. Tamamlandığında, çıktı, UI'nin kolayca çalışabileceği bazı görüntü kapsayıcı sınıfın doldurulmuş dizisidir.UI dizisindeki BitmapImage işlemlerine alternatif mi?

İlk düşüncem BitmapImage sınıfını görüntü kabı olarak kullanmaktı; Ancak, herhangi bir UI olmayan iş parçacığının erişimini kısıtlayacak olan DependencyObject sınıfından miras alınır. @Filip bu sorunun daha önceki formunda da belirttiği gibi, bu doğal olarak bir sorun değildir, ama işçi sınıfımın genelliğini kısıtlar.

Görüntü kapsayıcısının temeli olarak kullanabileceğim daha iyi bir Windows sınıfı var ve sonra bağlama zamanında UI iş parçacığı üzerinde BitmapImage dönüştürülüyor mu? Ya da daha iyi bir şekilde birlikte mi? Kaynak görüntüler için bir dizi URI kullanarak, yapmaya çalıştığımı belirtmek için bazı sahte kodlar. (Daha sonraki bir zamanda) işçi sınıfının UI iş parçacığı üzerinde

ImageContainerClass[] prepImages(Uri[] uriSet) 
{ 
    ImageContainerClass[] iccSet = new ImageContainerClass[uriSet.Length]; 
    for (int i = 0; i < iccSet.Length; i++) 
     iccSet[i] = new ImageContainerClass.retrieveImage(uriSet[i]); 
    return iccSet; 
} 

yılında

:

BitmapImage bmi = new BitmapImage(); 
var image = iccSet[i].getImage(); 
<<some operation to set the source of bmi to the image>> 
someImage.Source = bmi; 
+0

UI olmayan bir iş parçacığında BitmapImage örneklerini (veya BitmapSource'tan türetilmiş başka bir sınıfın örneklerini) kolayca oluşturabilir ve sonra bunları UI iş parçacığında kullanabilirsiniz. Onları çapraz iş parçacığı erişilebilir hale getirmek için 'Freeze()' yöntemini çağırdığınızdan emin olmanız gerekir. – Clemens

+0

Merhaba Clemens - bunun için teşekkürler. Tam olarak anladığımdan emin değilim. Soruların Cpl: (*) Windows.UI.Xaml.Media.Imaging.BitmapImage kullanıyorum; Freeze yöntemi yok gibi görünüyor? Var olduğuna dair başka kanıtlar görüyorum; belki yeni/farklı bir sınıf hiyerarşisinde miyim? (*) Örneği yaratma eylemi bir iplik hatasıyla bombalanır; UI iş parçacığı üzerinde oluşturmalıyım, Freeze (bir şekilde) ve sonra arka plan iş parçacığına geçmek zorunda mıyım? – jbhelicon

+0

Soru etiketlerinizden 'wpf' kaldırdım ve' win-universal-app' eklendi. Lütfen bunların farklı çerçeveler olduğunu unutmayın. – Clemens

cevap

1

Tamam, işte işe yarayacak bir çözüm var. Aşağıdaki kod olmayan bir UI iş parçacığı üzerinde mutlulukla çalışacağı

: Resmin görüntülendiği gerektiğinde Sonra

internal async Task<InMemoryRandomAccessStream> getImage(Uri uri) 
    { 
     try { 
      var httpClient = new HttpClient(); 
      IBuffer iBuffer = await httpClient.GetBufferAsync(uri); 
      byte[] bytes = iBuffer.ToArray(); 
      InMemoryRandomAccessStream ims = new InMemoryRandomAccessStream(); 
      DataWriter dataWriter = new DataWriter(ims); 
      dataWriter.WriteBytes(bytes); 
      await dataWriter.StoreAsync(); 
      ims.Seek(0); 
      return ims; 
     } catch (Exception e) { return null; } 
    } 

, aşağıdaki kod UI iş parçacığı üzerinde yürütülen edilebilir:

BitmapImage bmi = new BitmapImage(); 
bmi.SetSource(ims); 
someImage.Source = bmi; 

Bunun ilgili çerçevelere daha aşina olan insanlar tarafından temizlenebileceğine eminim, ancak umarım bu başkalarına yardımcı olacaktır. Beni doğru yola koyduğunuz için @Filip'e teşekkürler.

1

ben BitmapImage içine görüntüleri yükleme düşünüyorum bu yüzden orada, platformda bir arka plan iş parçacığı üzerinde olur Yapman gerekmiyor. Gerek duyduysanız ve bir piksel tamponunu WriteableBitmap içine itip belki de arka plan iş parçacığı üzerinde BitmapDecoder kullanabilirsiniz, ancak bundan çok kazanamazsınız. Tüm kodu bir arka plan iş parçacığına zorlamak istiyorsanız, DirectX interop'unu kullanabilir ve eşyalarınız için tamamen ayrı bir arka plan iş parçacığına sahip olabilirsiniz.

+0

Merhaba Filip. Bunun için teşekkürler. Soruna, hangi yapmaya çalıştığımı açıklamaya yardımcı olabilecek bir kod ekledim. – jbhelicon

+0

Evet, hayır. Bu kod hızlı çalışmalı. –

+0

Merhaba Filip. Aptal olduğum için üzgünüm; "Evet, hayır" ne demek bilmiyorum? Ve "o kod" dediğinizde hangi kodu kastediyorsunuz? Kodunu kastettiğini mi sanıyorum? [Kodum hiç çalışmıyor] – jbhelicon