Answered by:
The application called an interface that was marshalled for a different thread.

Question
-
Please If I have this code in my DataGathering class is not a partial class, It was work correctly but now it cause this exception.
Problems at underline lines.
The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))
Please what is the problem,and what is the solution?
foreach (ParseFile Photo in Photos) { if (Photo != null) { byte[] data =await new HttpClient().GetByteArrayAsync(Photo.Url).ConfigureAwait(false); BitmapImage image = await ByteArrayToBitmapImage(data).ConfigureAwait(false); ListOfImages.Add(image); } } ImagesAsSource.Add(x.ObjectId, ListOfImages);}
public static async Task<BitmapImage> ByteArrayToBitmapImage(Byte[] pixels)
{
var stream = new InMemoryRandomAccessStream();
await stream.WriteAsync(pixels.AsBuffer());
stream.Seek(0);
var image = new BitmapImage();
await image.SetSourceAsync(stream);
return image;
}
Sunday, December 15, 2013 10:11 PM
Answers
-
Being a partial class or not isn't relevant to the problem.
As the error says, the problem is the thread on which the call occurs: the app cannot manipulate UI elements from non-UI threads. In this case the problems are the BitmapImage and ListOfImages.
To fix this, move the calls to those methods to the UI thread by calling Dispatcher.RunAsync. This will look something like:
await Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,async ()=> { BitmapImage image = await ByteArrayToBitmapImage(data).ConfigureAwait(false); ListOfImages.Add(image); });
For more details please see the Dispatcher.RunAsync documentation I linked previously.
--Rob
- Marked as answer by Jeff SandersMicrosoft employee, Moderator Wednesday, December 18, 2013 4:36 PM
Monday, December 16, 2013 9:45 PMModerator
All replies
-
The error says you need to call that from your UI thread. To trigger that from a background thread use Dispatcher.RunAsync. See the linked ducks for example code.Monday, December 16, 2013 3:33 PMModerator
-
If the class is not a partial class, Are there any impacts?
Please, Is it possible to give me more information?Monday, December 16, 2013 5:28 PM -
The problem is that you may not interact with the UI or UI elements such as BitmapImage from a non-UI thread. Using the Dispatcher will cause the UI thread to interact with those elements so that the work can get done.
Matt Small - Microsoft Escalation Engineer - Forum Moderator
If my reply answers your question, please mark this post as answered.
NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.Monday, December 16, 2013 6:41 PMModerator -
I am so sorry,I will clarification.
The purpose of this code is to get data from the database and refitted into group using this class (DataGathering.cs).
I will get the Group (Observable Collection) after this class finished.
public sealed class DataGathering { private ObservableCollection<SubCitiseInCity> _groups = new ObservableCollection<SubCitiseInCity>(); public ObservableCollection<SubCitiseInCity> Groups { get { return this._groups; } } public static async Task GetDataAsync_Rent_Sell(string TableName, string Type, string City) { await ConnectToDB(TableName, Type, City); if(!Error) _dataGathering.GetData_Rent_Sell(); } private static async Task ConnectToDB(string TableName, string Type, string City_University) { tableName = TableName; Error = false; try { if (Type != "") { ParseQuery<ParseObject> query_ = ParseObject.GetQuery(TableName); ParseQuery<ParseObject> query = from Realties in query_ where Realties.Get<string>("type").Equals(Type) && Realties.Get<string>("City").Equals(City_University) select Realties; results = await query.FindAsync(); foreach (ParseObject x in results) { string subcity = (string)x["subCity"]; List<ParseObject> ItemsInSubCity; if (SubCities.ContainsKey(subcity)) { ItemsInSubCity = SubCities[subcity]; } else { ItemsInSubCity = new List<ParseObject>(); SubCities.Add(subcity, ItemsInSubCity); } ItemsInSubCity.Add(x); //***************************** await ImageOwnerInfo(x); } } } catch { Error = true; } } private static async Task ImageOwnerInfo(ParseObject x) { List<BitmapImage> ListOfImages = new List<BitmapImage>(); ParseFile[] Photos = new ParseFile[3]; try { Photos[0] = x.Get<ParseFile>("Photo1"); Photos[1] = x.Get<ParseFile>("Photo2"); Photos[2] = x.Get<ParseFile>("Photo3"); } catch { } foreach (ParseFile Photo in Photos) { if (Photo != null) { byte[] data = await new HttpClient().GetByteArrayAsync(Photo.Url).ConfigureAwait(false); BitmapImage image = await ByteArrayToBitmapImage(data).ConfigureAwait(false); ListOfImages.Add(image); } } ImagesAsSource.Add(x.ObjectId, ListOfImages);} private void GetData_Rent_Sell() { if (this._groups.Count != 0) return; foreach (KeyValuePair<string, List<ParseObject>> subcity in SubCities) { ........... RealtiesSubCity group2 = new RealtiesSubCity(realty.ObjectId,(string)realty["Street"], (string)realty["Neighborhood"], (string)realty["detailAddress"], Date,(string)realty["Room"],(string)realty["BathRoom"],(string)realty["Parking"],(string)realty["Asan"], (string)realty["area"], (string)realty["JDprice"], (string)realty["dollarPrice"], (string)realty["negotiable"], (string)realty["description"], ImagesAsSource[realty.ObjectId], ImagesAsSource[realty.ObjectId].First(), theOwner, title_, (string)realty["type"], rent); group1.Items.Add(group2); } this.Groups.Add(group1); } } public static async Task<BitmapImage> ByteArrayToBitmapImage(Byte[] pixels) { var stream = new InMemoryRandomAccessStream(); await stream.WriteAsync(pixels.AsBuffer()); stream.Seek(0); BitmapImage image = new BitmapImage(); await image.SetSourceAsync(stream); return image; } public class RealtiesSubCity {.......................... } public class SubCitiseInCity { ................ } } }
In the FirstPage.xaml.cs I will do thisprivate async void GetDatatoPage() { ................. await DataGathering.GetDataAsync_Rent_Sell(Info[1], Info[2], Info[3]); ............... } private void SubCity_SelectionChanged(object sender, SelectionChangedEventArgs e) { string subcity = SubCity.SelectedItem.ToString(); var group = DataGathering.SubCityAsync(subcity); if (group != null) { NoElements.Visibility = Visibility.Collapsed; this.DefaultViewModel["Items"] = group.Items;//Binding in XAML page } else { this.DefaultViewModel["Items"] = null; NoElements.Visibility = Visibility.Visible; } }
I hope to be clear.
- Edited by GhadaNaim Monday, December 16, 2013 7:44 PM
Monday, December 16, 2013 7:43 PM -
Being a partial class or not isn't relevant to the problem.
As the error says, the problem is the thread on which the call occurs: the app cannot manipulate UI elements from non-UI threads. In this case the problems are the BitmapImage and ListOfImages.
To fix this, move the calls to those methods to the UI thread by calling Dispatcher.RunAsync. This will look something like:
await Window.Current.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,async ()=> { BitmapImage image = await ByteArrayToBitmapImage(data).ConfigureAwait(false); ListOfImages.Add(image); });
For more details please see the Dispatcher.RunAsync documentation I linked previously.
--Rob
- Marked as answer by Jeff SandersMicrosoft employee, Moderator Wednesday, December 18, 2013 4:36 PM
Monday, December 16, 2013 9:45 PMModerator -
I am so sorry, but the above code cause :
Exception:Caught: "Object reference not set to an instance of an object." (System.NullReferenceException)
Monday, December 16, 2013 10:47 PM -
When you debugged it which object was null?
Depending on where you call this from you may need to cache the Dispatcher from the UI thread and use that rather than trying to query it directly.
--Rob
Monday, December 16, 2013 11:08 PMModerator