Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > C# and C > C# 4.0 aka C# 2010 > C# 4.0 aka C# 2010 General Discussion
Password Reminder
Register
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
C# 4.0 aka C# 2010 General Discussion Discussions about the C# 4.0, C# 4, Visual C# 2010 language and tool not related to any specific Wrox book
Welcome to the p2p.wrox.com Forums.

You are currently viewing the C# 4.0 aka C# 2010 General Discussion section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
 
 
Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old August 3rd, 2011, 09:57 AM
Authorized User
 
Join Date: May 2007
Location: Hyderabad, Andhra Pradesh, India.
Posts: 95
Thanks: 5
Thanked 0 Times in 0 Posts
Default invalid cross thread acces exception on creating a new bitmap image

Hi All

I am writing a class using C# 4.0, silverlight 4 and VS 2010. I have written a class which should return a bitmap image. Here is the code

Code:
 public BitmapImage base64StringToImage(string base64String)
        {
            Byte[] imageBytes = Convert.FromBase64String(base64String);
            BitmapImage bmImage1 = null;
            BitmapImage bmImage = null;
            using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
            {
                ms.Write(imageBytes, 0, imageBytes.Length);
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        bmImage = new BitmapImage();
                        
                       
                    });
                bmImage.SetSource(ms);
                bmImage1 = bmImage;
                //bmImage.SetSource(ms);
            }
            return bmImage1;
        }
This returns 'Object reference not set to an instance of an object' error
I am using the dispatcher.invoke() method because it gives invalid cross thread exception error. And anything under that method doesnt instantiate first. Now if I do some modification like placing and instantiating the bitmapimage object inside the dispatcher method and then assigning its value to externally declared bitimageobject , the error goes but null value gets assigned. I am not able to understand what to do next and what code I need to modify or add? Please help...


-- Abhishek
  #2 (permalink)  
Old August 6th, 2011, 07:58 AM
Authorized User
 
Join Date: May 2007
Location: Hyderabad, Andhra Pradesh, India.
Posts: 95
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Can I expect some sort of reply from experts. I am using MVVM model.
  #3 (permalink)  
Old August 6th, 2011, 08:51 AM
Wrox Author
Points: 1,163, Level: 13
Points: 1,163, Level: 13 Points: 1,163, Level: 13 Points: 1,163, Level: 13
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Sep 2010
Location: Austria
Posts: 175
Thanks: 3
Thanked 53 Times in 53 Posts
Default

Hi Abhishek,

Quote:
Originally Posted by abhishekkashyap27 View Post
Can I expect some sort of reply from experts.
Please don't be indignant as the "experts" are often themselves deep into projects and during that time of the year sometimes on vacation and thus can't respond to all the questions immediately as this is also done in the spare time. For urgent issues a hotline might be helpful.

Regarding to the original question, you use the bmImage before creating it. The method BeginInvoke starts asynchronously in the thread that has the synchronization context, and before the thread starts its work you're invoking the SetSource method on this object. That's why there's a null reference exception. The Invoke method is the synchronous variant. Check the chapter Threads, Tasks, and Synchronization in the book Professional C# 4 and .NET 4.

The invalid cross thread exception error is exactly the reason why you need to use the Dispatcher. However, it's usually not only the instantiation of the object. Why is the base64StringToImage mehod running in a separate thread? Can you give more details on how this is used and where the exception happens?

Christian

Quote:
Originally Posted by abhishekkashyap27 View Post

Code:
 public BitmapImage base64StringToImage(string base64String)
        {
            Byte[] imageBytes = Convert.FromBase64String(base64String);
            BitmapImage bmImage1 = null;
            BitmapImage bmImage = null;
            using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
            {
                ms.Write(imageBytes, 0, imageBytes.Length);
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        bmImage = new BitmapImage();
                        
                       
                    });
                bmImage.SetSource(ms);
                bmImage1 = bmImage;
                //bmImage.SetSource(ms);
            }
            return bmImage1;
        }
__________________
Christian
CN innovation
Visit my blog at: csharp.christiannagel.com
Follow me on twitter: @christiannagel
  #4 (permalink)  
Old August 6th, 2011, 09:12 AM
Authorized User
 
Join Date: May 2007
Location: Hyderabad, Andhra Pradesh, India.
Posts: 95
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Hi

Thanks for the response. I am using MVVM pattern with C# 4.0 and silverlight.
I am trying to display images by converting the byte array into bitmap images. But whenever I am trying to convert bitmap images, I got invalid cross thread access exception. I did some research and found out a way to fix it, that is using the autoresetevent class and dispatcher.invoke() delegate. Now whats the problem is that byte array is converted into images and added into collection classes but when rendering into browser, it shows only one type of image.( If count of images is 9, then image of last count gets displayed 9 times), You can see that I have kept the break statement specifically to check this. Now what I am thinking is that, whether I have issues with thread(threading not working properly or bad/improper code) or binding is not done properly.
Here is the entire code
Code:
namespace Infor.Plm.ItemModule.ViewModels
{
    #region NAMESPACES
    using Infor.Plm.Common;
    using System.Collections.Generic;
    using System.Xml;
    using System.Xml.Xsl;
    using System.Xml.Linq;
    using System.Xml.XPath;
    using System;
    using System.IO;
    using System.ComponentModel;
    using System.Windows.Controls;
    using System.Windows.Media.Imaging;
    using System.Windows.Data;
    using System.Collections.ObjectModel;
    using System.Threading;
    using System.Windows;
    using Microsoft.Practices.Prism.ViewModel;

    #endregion

    /// <summary>
    /// Creating a class
    /// </summary>
    /// 
    public class ImageOneClass : NotificationObject
    {
        private string imageFileName;
        public string ImageFileName
        {
            get { return imageFileName; }
            set { imageFileName = value; RaisePropertyChanged("ImageFileName"); }
        }


        private string imageDocName;
        public string ImageDocName
        {
            get { return imageDocName; }
            set { imageDocName = value; RaisePropertyChanged("ImageDocName"); }
        }
      

        private BitmapImage _imageOne;
        public BitmapImage ImageOne
        {
            get { return _imageOne; }
            set { _imageOne = value; RaisePropertyChanged("ImageOne"); }
        }

    }
    
    public class ThumbnailsViewModel : INotifyPropertyChanged
    {
        

        List<BitmapImage> objbmp = new List<BitmapImage>();
        public string base64String = string.Empty;
        public BitmapImage bmImage1 = new BitmapImage();
        public BitmapImage bmImage2 = new BitmapImage();


        public void LoadObjectData(string objectKey, string objectRevision, string mode,
                                            DateTime? date,
                                            string revisionOptionValue,
                                            string executeFilter,
                                            ObjectType ObjType)
        {

            string MethodId = objectKey + "_" + objectRevision + "_";
            RequestBuilder rqsBuilder = new RequestBuilder();

            // Creating root element
            XElement xelemRoot = rqsBuilder.BuildRootElement(RequestBuilder.Request);

            // Creating connection info element
            XElement elemConnInfo = ConnectionManager.GetConnectInfoElement();

            // Creating method element name
            XElement rootElemMethod = rqsBuilder.BuildRootElement(RequestBuilder.Method);
            XElement elemMethodName = rqsBuilder.BuildElementWithValue(RequestBuilder.Name, RequestBuilder.GetThumbnail);
            XElement elemMethodId = rqsBuilder.BuildElementWithValue(RequestBuilder.MethodID, MethodId);

            // Creating For element name
            XElement elemFor = rqsBuilder.BuildCreateForElement("DOC", objectKey, objectRevision);

            // creating ExtrainfoFor element name
            XElement elemInfoFor = new XElement(CreateExtraInfoFor());

            // Building the final xml
            xelemRoot.Add(elemConnInfo);

            rootElemMethod.Add(elemMethodName);
            rootElemMethod.Add(elemMethodId);
            rootElemMethod.Add(elemFor);
            rootElemMethod.Add(elemInfoFor);

            xelemRoot.Add(rootElemMethod);
            this.LoadDataForThumbnails(xelemRoot.ToString());

        }
        private void LoadDataForThumbnails(string reqQueryString)
        {
            ServerRequest request = new ServerRequest();
            request.ProcessResponse += new EventHandler<ProcessResponseArgs>(this.ProcessXMLOnServerResponse);
            request.SendRequst(reqQueryString);
        }
        private void ProcessXMLOnServerResponse(object sender, ProcessResponseArgs e)
        {
            //Response
            XDocument doc = XDocument.Parse(e.Result);
            string expression = "MethodResponse/DeResult/NewDataSet/Table";

            XElement eleResult = doc.Root.XPathSelectElement("MethodResponse/DeResult/NewDataSet/Table");
            
            if (eleResult == null)
            {
                //List<ImageOneClass> chk = new List<ImageOneClass>();
                //chk.Add(new ImageOneClass() {  });
                //this.ImageUri = new Uri("../Resources/ThumbnailNotAvailable.jpg", UriKind.Relative);
                

            }
            else
            {
                string chk = string.Empty;
                List<ImageOneClass> bitmapImageCollection = new List<ImageOneClass>();
                int I = 0;
                foreach (XElement elm in doc.Root.XPathSelectElements(expression))
                {
                    I++;
                    if (I == 8)
                        break;
                    XElement dsetKeyEle = elm.XPathSelectElement("DSET_KEY");
                    XElement revisionEle = elm.XPathSelectElement("DSET_REVISION");
                    XElement objKeyEle = elm.XPathSelectElement("OBJECT_KEY");
                    XElement objRevEle = elm.XPathSelectElement("OBJECT_REVISION");

                    XElement imageEle = elm.XPathSelectElement("THUMBNAIL");

                    if (chk == string.Empty)
                    {
                        chk = imageEle.Value;
                    }
                    else
                    {
                        if (chk == imageEle.Value)
                        {
                            System.Windows.MessageBox.Show("Thumbnail byte code same!", "ALERT", System.Windows.MessageBoxButton.OK);
                        }
                    }
                    
                    bitmapImageCollection.Add(new ImageOneClass() { ImageOne = base64StringToImage(imageEle.Value), 
                                                                    ImageFileName = string.Format("{0} - {1}",dsetKeyEle.Value,revisionEle.Value),
                                                                    ImageDocName = string.Format("{0} - {1}", objKeyEle.Value, objRevEle.Value)
                    });

                   

                }
               
                this.Images = bitmapImageCollection;
            }
        }

      
        private List<ImageOneClass> images;
        public List<ImageOneClass> Images
        {
            get { return images; }
            set { images = value; NotifyPropertyChanged("Images"); }
        }

    
        public BitmapImage base64StringToImage(string base64String)
        {
            
            Byte[] imageBytes = Convert.FromBase64String(base64String);
            using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
            {
                ms.Write(imageBytes, 0, imageBytes.Length);
                using (AutoResetEvent are = new AutoResetEvent(false))
                {
                    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                        {
                            bmImage1.SetSource(ms);
                            are.Set();
                        });
                    are.WaitOne();
                    ms.Close();
                    ms.Dispose();
               }
             
            }
            //Thread.Sleep(1000);
            //BitMapImageCheck(bmImage1);
            return bmImage1;
        }

        private void BitMapImageCheck(BitmapImage bmp)
        {
            //List<object> objbmp = new List<object>();
            objbmp.Add(bmp);
        }


        private XElement CreateExtraInfoFor()
        {
            XElement xelemExtraInfoFor = new XElement("ExtraInfoFor");
            XElement xelemObject = new XElement("Object", "DATASET");
            XElement xelemField = new XElement("Fields", new XElement("DSET_NAME"), new XElement("FORMAT"));
            xelemExtraInfoFor.Add(xelemObject);
            xelemExtraInfoFor.Add(xelemField);
            return xelemExtraInfoFor;
        }

        /*
        private Uri _imageUri;
        public Uri ImageUri
        {
            get { return _imageUri; }
            set { _imageUri = value; NotifyPropertyChanged("ImageUri"); }
        }
        */
        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Notifies the property changed.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        protected virtual void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                    });
            }
        }


    }
    
    public class UriToImageSourceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            // No checks...
            BitmapImage bmi = (new BitmapImage((Uri)value));
            return bmi;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
     
}
The method is ProcessXMLOnServerResponse(), this method will inturn call the base64StringToImage() method, as you can see it.

Here is my xaml file where is it binded:

Code:
<UserControl xmlns:my="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"  x:Class="Infor.Plm.ItemModule.Views.Thumbnails"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:common="clr-namespace:Infor.Plm.Common;assembly=Infor.Plm.Common"
    xmlns:vm="clr-namespace:Infor.Plm.ItemModule.ViewModels;assembly=Infor.Plm.ItemModule"
   
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.DataContext>
        <vm:ThumbnailsViewModel />
    </UserControl.DataContext>
    <UserControl.Resources>
        <vm:UriToImageSourceConverter x:Key="UriToImageSourceConverter" />
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.Resources>

        </Grid.Resources>
        <!--<my:WrapPanel Orientation="Horizontal">-->
        <ItemsControl ItemsSource="{Binding Images}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <my:WrapPanel Orientation="Horizontal">
                        <Image Name="imgThumbnails"  Source="{Binding ImageOne}" FlowDirection="LeftToRight"  />
                        <TextBlock Name="txt"/>
                        <TextBlock Text="{Binding ImageFileName}" />
                        <TextBlock Text="{Binding ImageDocName}" />
                        </my:WrapPanel>
                    </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <!--</my:WrapPanel>-->
    </Grid>
</UserControl>
What I am doing wrong? What code should I modify?
Please do understand that I am new to Silverlight and C# 4.0

-- Abhishek
  #5 (permalink)  
Old August 6th, 2011, 09:33 AM
Authorized User
 
Join Date: May 2007
Location: Hyderabad, Andhra Pradesh, India.
Posts: 95
Thanks: 5
Thanked 0 Times in 0 Posts
Default

I have checked it that before getting converted into images, all the byte codes are different and none of them are same. Is something wrong going on in the base64StringtoImage() method? or binding is wrong?
  #6 (permalink)  
Old August 6th, 2011, 09:47 AM
Wrox Author
Points: 1,163, Level: 13
Points: 1,163, Level: 13 Points: 1,163, Level: 13 Points: 1,163, Level: 13
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Sep 2010
Location: Austria
Posts: 175
Thanks: 3
Thanked 53 Times in 53 Posts
Default

Within the method base64StringtoImage the variable bmImage1 is returned which now is a member of the class. If the method base64StringtoImage is called multiple times, bmImage1 is overwritten.
__________________
Christian
CN innovation
Visit my blog at: csharp.christiannagel.com
Follow me on twitter: @christiannagel
  #7 (permalink)  
Old August 6th, 2011, 09:56 AM
Authorized User
 
Join Date: May 2007
Location: Hyderabad, Andhra Pradesh, India.
Posts: 95
Thanks: 5
Thanked 0 Times in 0 Posts
Default

What modification shall I do in the code in the base64StringtoImage method? Please help...., I have almost lost patience........


-- Abhishek
  #8 (permalink)  
Old August 6th, 2011, 10:04 AM
Authorized User
 
Join Date: May 2007
Location: Hyderabad, Andhra Pradesh, India.
Posts: 95
Thanks: 5
Thanked 0 Times in 0 Posts
Default

By the way, how the variable bmImage will be over written? Even everytime the method base64StringtoImage() is called, the value is retunred and it is added into collection classes? Isnt it?
  #9 (permalink)  
Old August 6th, 2011, 10:56 AM
Authorized User
 
Join Date: May 2007
Location: Hyderabad, Andhra Pradesh, India.
Posts: 95
Thanks: 5
Thanked 0 Times in 0 Posts
Default

Christian

Sorry for bothering too much! I do understand that you guys are busy but I really need to know what should I modify in the method base64StringtoImage() if the variable is getting overwritten. I have declared the variable bmImage1 globally so that the error 'Invalid cross thread exception' gets removed.
  #10 (permalink)  
Old August 6th, 2011, 11:04 AM
Wrox Author
Points: 1,163, Level: 13
Points: 1,163, Level: 13 Points: 1,163, Level: 13 Points: 1,163, Level: 13
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Sep 2010
Location: Austria
Posts: 175
Thanks: 3
Thanked 53 Times in 53 Posts
Default

Quote:
Originally Posted by abhishekkashyap27 View Post
By the way, how the variable bmImage will be over written? Even everytime the method base64StringtoImage() is called, the value is retunred and it is added into collection classes? Isnt it?
Within the constructor of the class ThumbnailsViewModel a new instance of bmImage1 is created.

Code:
   public class ThumbnailsViewModel : INotifyPropertyChanged
    {
        List<BitmapImage> objbmp = new List<BitmapImage>();
        public string base64String = string.Empty;
        public BitmapImage bmImage1 = new BitmapImage();
And this instance is returned from the method base64StringtoImage. So you are returning a reference to the same object and put the same object multiple times into the collection. You need to create a new instance of the BitmapImage every time base64StringtoImage is invoked.
__________________
Christian
CN innovation
Visit my blog at: csharp.christiannagel.com
Follow me on twitter: @christiannagel
The Following User Says Thank You to ChristianNagel For This Useful Post:
abhishekkashyap27 (August 6th, 2011)
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Cross-Thread Error ricespn Visual Basic 2008 Essentials 0 July 16th, 2009 02:33 PM
cross thread exception YoungLuke C# 1 March 23rd, 2008 06:46 PM
cross thread exception with windows live API YoungLuke C# 2008 aka C# 3.0 1 March 23rd, 2008 01:43 PM
cross thread Error angelboy C# 2005 1 July 28th, 2007 04:35 AM
Cross-thread operation not valid Richw71 C# 0 December 13th, 2006 09:17 AM



All times are GMT -4. The time now is 07:15 PM.


Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.