I am loading the images using the BackgroundThread. I am receving "nullreferenceexception unhandled by user code" after loading all the images into the Listview. What could be the issue? Please let me know.
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
int progress = 0;
string pname;
Image myImage;
max_length = files.Length;
for (int k = 0; k < files.Length; k++)
{
ProgressInfo info = new ProgressInfo();
pname = System.IO.Path.GetFullPath(files[k]);
myImage = Image.FromFile(pname);
info.Image = myImage;
info.ImageIndex = k;
backgroundWorker1.ReportProgress(progress, info);
myImage = null;
}
}
catch (Exception ex)
{
throw ex.InnerException;
}
}
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
try
{
//Get image.
ProgressInfo img = e.UserState as ProgressInfo;
//Set image to ListView here.
ImgListView.Images.Add(getThumbnaiImage(ImgListView.ImageSize.Width, img.Image));
fname = System.IO.Path.GetFileName(files[img.ImageIndex]);
ListViewItem lvwItem = new ListViewItem(fname, img.ImageIndex);
lvwItem.Tag = files[img.ImageIndex];
lstThumbNailView.Items.AddRange(new ListViewItem[] { lvwItem });
percent = (int)((float)100 * (float)i / (float)files.Length);
this.progressBar1.Value = (int)percent;
this.label1.Text = "Loading images...";
}
catch (Exception ex)
{
throw ex.InnerException;
}
}
Judging from your comments, you're seeing the error because not all exceptions have an InnerException. If InnerException is null, you will see this problem.
There are several issues at work here though. First, here is the proper try/catch method:
try
{
// Code here
}
catch (Exception ex)
{
// Handle your exception
throw; // Rethrow the same exception, preserving the stack trace (optional)
}
Second, you are likely abusing the purpose of ReportProgress. You should attempt to do all your logic in your backgroundWorker_DoWork, and send the percentage (between 0 and 100) to ReportProgress to update any progress bars.
You may have used the ReportProgress in the way you did to fix a multi-threaded issue. To add items to a ListBox across threads, wrap your code in an anonymous method using the BeginInvoke function
Example:
// Note: I haven't error checked this, and this is only a rough idea of what
// you're trying to do. I'm not even sure of the overall goal here.
this.lstThumbnailView.Invoke((Action)delegate
{
ListViewItem lvwItem = new ListViewItem(name, img.ImageIndex);
ivwItem.Tag = files[img.ImageIndex];
lstThumbNailView.Items.Add(lvwItem);
});
Thanks for the quick response. Here are the changes I made. It seems to be working fine.
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
try
{
ProgressInfo img = e.UserState as ProgressInfo;
LoadImages(img);
this.progressBar1.Value = img.Percent;
this.label1.Text = "Loading images...";
}
catch (Exception ex)
{
throw ex;
}
}
private void LoadImages(ProgressInfo img)
{
ImgListView.Images.Add(getThumbnaiImage(ImgListView.ImageSize.Width, img.Image));
this.lstThumbNailView.Invoke((Action)delegate
{
fname = System.IO.Path.GetFileName(files[img.ImageIndex]);
ListViewItem lvwItem = new ListViewItem(fname, img.ImageIndex);
lvwItem.Tag = files[img.ImageIndex];
lstThumbNailView.Items.Add(lvwItem);
});
}
Related
I keep getting a "Parameter is not valid" error or a memory leak (and the picture doesn't update) when I run my code. I am trying to get frames from a local IP camera using AForge.Net. The exact error code that I get is:
"An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll
Parameter is not valid."
In my code, feed is the name of the winforms picture box.
private void Form1_Load(object sender, EventArgs e) {
Console.WriteLine(camaddress);
stream.Source = camaddress;
stream.Login = camUser;
stream.Password = camPass;
stream.Start();
//PictureBox.CheckForIllegalCrossThreadCalls = false;
CaptureCamera();
isCameraRunning = true;
}
private void CaptureCamera() {
try {
camera = new Thread(new ThreadStart(CaptureCameraCallback));
camera.Start();
} catch (Exception e) {
Debug.Write("Exception encountered trying to capture camera:\n" + e.ToString() + "\n");
}
}
private void CaptureCameraCallback() {
log.Information("Camera Opened", testID);
guiLogWrite("Camera Opened");
while (stream.IsRunning) {
stream.NewFrame += new NewFrameEventHandler(VideoStream_NewFrame);
}
}
private void VideoStream_NewFrame(object sender, NewFrameEventArgs eventArgs) {
try {
//Image FrameData = new Bitmap(eventArgs.Frame);
if (feed.Image != null) feed.Image.Dispose();
Bitmap FrameData = AForge.Imaging.Image.Clone(eventArgs.Frame);
SetPicture(FrameData);
FrameData.Dispose();
} catch { }
}
private void SetPicture(Image img) {
if (this.InvokeRequired) {
this.Invoke(new MethodInvoker(delegate { SetPicture(img); }));
} else {
this.feed.Image = img;
}
This is my first time posting on Stack Overflow so please let me know if I have forgotten something. I've spent hours looking at other stackoverflow threads and Google trying to find a solution.
I am trying to make a text box in a WPF C# application populate a text box from a variable gathered from an external database using WCF and having little luck. Currently the text box states ScoreBoardClientTest.FeedServiceAgent instead of the value of agentsavailable. I was able to make this exact same code work in a console application when using this line of code inside of OnMessageReceived
console.writeline(e.cmsdata.skill.agentsavailable.tostring());
so I assumed I could do something similar here.
any help understanding where I'm going wrong would be great.
DisplayNumber is the name of the textbox.
public void TextBlock_Loaded(object sender, EventArgs e)
{
using (var data = new FeedServiceAgent())
{
data.MessageReceived += OnMessageReceived;
data.Subscribe("92", 3);
DisplayNumber.Text = data.ToString();
}
}
public static void OnMessageReceived(object sender, MessageReceivedEventArgs e)
{
try
{
if (e == null)
return;
if (e.CmsData == null)
{
e.CmsData.Skill.AgentsAvailable.ToString();
}
// if (!String.IsNullOrEmpty(e.Message))
// Console.WriteLine(e.Message);
}
catch (Exception ex)
{
// logger.Error(" Exception " + ex);
// throw ex;
}
}
Edit
Changed:
DisplayNumber.Text =e.CmsData.Skill.AgentsAvailable.ToString();
to:
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => { DisplayNumber.Text = e.CmsData.Skill.AgentsAvailable.ToString() ; }
This will handle multithreaded calls. You might have to add a using System.Threading statement for the DispatcherPriority enum
EndEdit
It is still unclear how to get from the data of Type FeedServiceAgent to a Skill.AgentsAvailable property in your Loaded event handler. We need more information on how to make that navigation. Is the assignment even necessary in the Loaded handler? I've marked the location in the code below.
I've also made what appears to be the necessary changes to the message handler method.
public void TextBlock_Loaded(object sender, EventArgs e)
{
using (var data = new FeedServiceAgent())
{
data.MessageReceived += OnMessageReceived;
data.Subscribe("92", 3);
//DisplayNumber.Text = data.ToString();
//Is this assignment even necessary?
DisplayNumber.Text = /*Still unclear what goes here because we don't know what how to get from `data` to `Skill`*/
}
}
public static void OnMessageReceived(object sender, MessageReceivedEventArgs e)
{
try
{
if (e == null)
return;
if (e.CmsData == null)
{
//e.CmsData.Skill.AgentsAvailable.ToString();
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => { DisplayNumber.Text = e.CmsData.Skill.AgentsAvailable.ToString() ; }));
}
// if (!String.IsNullOrEmpty(e.Message))
// Console.WriteLine(e.Message);
}
catch (Exception ex)
{
// logger.Error(" Exception " + ex);
// throw ex;
}
}
I am developing an application in Windows Phone Silverlight 8.1 in which I am trying to set a route between current location and a hardcoded destination using this link the code is:
private async void GetCoordinates()
{
Geolocator myGeolocator = new Geolocator();
myGeolocator.DesiredAccuracyInMeters = 50;
Geoposition myposition = null;
try
{
myposition = await myGeolocator.GetGeopositionAsync(TimeSpan.FromMinutes(1),TimeSpan.FromSeconds(50));
Geocoordinate myGeocoordinate = myposition.Coordinate;
GeoCoordinate myGeoCoordinate = CoordinateConverter.ConvertGeocoordinate(myGeocoordinate);
mycoordinates.Add(new GeoCoordinate(myGeoCoordinate.Latitude, myGeoCoordinate.Longitude));
locationmap.Center = myGeoCoordinate;
locationmap.ZoomLevel = 13;
Mygeocodequery = new GeocodeQuery();
Mygeocodequery.SearchTerm = "Seattle, WA";
Mygeocodequery.GeoCoordinate = new GeoCoordinate(myGeoCoordinate.Latitude, myGeoCoordinate.Longitude);
Mygeocodequery.QueryCompleted += Mygeocodequery_Querycompleted;
Mygeocodequery.QueryAsync();
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Location is disabled in phone settings or capabilities are not checked.");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Mygeocodequery_Querycompleted(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
{
if(e.Error==null)
{
MyQuery = new RouteQuery();
mycoordinates.Add(e.Result[0].GeoCoordinate);
MyQuery.Waypoints = mycoordinates;
MyQuery.QueryCompleted += MyQuery_QueryCompleted;
MyQuery.QueryAsync();
Mygeocodequery.Dispose();
}
}
private void MyQuery_QueryCompleted(object sender, QueryCompletedEventArgs<Route> e)
{
try
{
**Route MyRoute = e.Result;**
MapRoute MyMapRoute = new MapRoute(MyRoute);
locationmap.AddRoute(MyMapRoute);
MyQuery.Dispose();
}
catch (TargetInvocationException ex)
{
MessageBox.Show(ex.InnerException.Message);
}
}
It sometimes works fine but sometimes I am getting this inner exception as TargetInvocationException Exception from HRESULT: 0x8004231C
On the line highlighted please let me know what should I do?
The Problem is only because I had skipped the step to write the following code in load event of map control
private void locationmap_Loaded(object sender, RoutedEventArgs e)
{
Microsoft.Phone.Maps.MapsSettings.ApplicationContext.ApplicationId = "yourapplicationID";
Microsoft.Phone.Maps.MapsSettings.ApplicationContext.AuthenticationToken = "yourauthenticationtoken";
}
if this code is added it works fine for all the locations.
Am quite new to this, so please help.
I have the following image clicked code.
However, an error will occur if the user does not click on a image.
How can i do an error check to catch that if the user does not click on an image and attempts to proceed, a messagebox will display notifying him to click an image.
Error msg: The error is at "ListViewItem selectedItem = listView1.SelectedItems[0] Error Msg: Invalid Argument = Value of '0' is not valid for 'index
Below is my code:
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int i = e.ProgressPercentage;
object fbUserObject = e.UserState;
if (fbUserObject is DataRow)
{
var fbUser = fbUserObject as DataRow;
var item = new ListViewItem(fbUser["friend_name"].ToString());
item.Tag = fbUser["friend_id"];
item.ImageIndex = i;
listView1.Items.Add(item);
}
else if (fbUserObject is Image)
{
imageList.Images.Add(fbUserObject as Image);
}
}
private void imageClicked(Object sender, System.EventArgs e)
{
ListViewItem selectedItem = listView1.SelectedItems[0];
selectedFBId = selectedItem.Tag as string;
selectedFBName = selectedItem.Text;
DialogResult dialogA = MessageBox.Show("Analyse employee data?", "SOC", MessageBoxButtons.YesNo);
if (dialogA == DialogResult.Yes)
{
TargetEmployee.Text = "Selected Target: " + selectedFBName;
pf.Show();
ThreadPool.QueueUserWorkItem(LoadUserDetails);
}
}
You shouldn't catch an exception, you should handle when there aren't any selected items
if(listView1.SelectedItems.Count == 0)
{
MessageBox.Show(this, "No image");
return;
}
Exceptions should be caught when you don't expect something to happen, if you are aware of a possible issue, you should handle that before it becomes an issue
change your code like this
private void imageClicked(Object sender, System.EventArgs e)
{
if(listView1.SelectedItems.Count < 1)
return;
ListViewItem selectedItem = listView1.SelectedItems[0];
selectedFBId = selectedItem.Tag as string;
selectedFBName = selectedItem.Text;
DialogResult dialogA = MessageBox.Show("Analyse employee data?", "SOC", MessageBoxButtons.YesNo);
if (dialogA == DialogResult.Yes)
{
TargetEmployee.Text = "Selected Target: " + selectedFBName;
pf.Show();
ThreadPool.QueueUserWorkItem(LoadUserDetails);
}
}
You can use a try { } catch { } statement for your error handling.
Once you locate the line of code that generates an exception, you can wrap it into a block like this
try
{
int a = int.Parse("pedantic"); // This throws an error because you cannot convert
}
catch (Exception e)
{
// Handle your error here instead of crashing your program
}
I want to merge two .png images. but when I ga to save them there occurred an error called a generic error occurred in gdi+. I want to continue my project as soon as possible. please help me. Thanks
private void MergeImages(string ImageBack,string ImageFore)
{
try
{
System.Drawing.Graphics myGraphic = null;
Image imgB;// =new Image.FromFile(ImageBack);
imgB = Image.FromFile(ImageBack);
//FileInfo fileInfoBack = new FileInfo(ImageBack);
Image imgF;// =new Image.FromFile(ImageBack);
imgF = Image.FromFile(ImageFore);
//Bitmap tempBitmap = new Bitmap(imgB.Width, imgB.Height,imgB.PixelFormat );
// tempBitmap.Save("a"+fileInfoBack.Extension);
Image m;
m = Image.FromFile(ImageBack);
// m = Image.FromFile("a" + fileInfoBack.Extension);
myGraphic = System.Drawing.Graphics.FromImage(m);
myGraphic.DrawImageUnscaled(imgB,0,0);
myGraphic.DrawImageUnscaled(imgF,posX,posY);
myGraphic.Save();
m.Save(ImageBack.Replace(".jpg",".jpeg"),System.Drawing.Imaging.ImageFormat.Jpeg);
//m.Save(ImageBack, System.Drawing.Imaging.ImageFormat.Png);
// m.Save("d.png", System.Drawing.Imaging.ImageFormat.Png);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void btnFileProtector_Click(object sender, System.EventArgs e)
{
if (openFileDialog1.ShowDialog()==DialogResult.OK)
{
txtFileProtector.Text=openFileDialog1.FileName;
}
}
private void btnFilesToProtect_Click(object sender, System.EventArgs e)
{
listFilesToProtect.Items.Clear();
if (openFileDialog2.ShowDialog()==DialogResult.OK)
{
if (openFileDialog2.FileNames.Length>0)
{
for(int i=0;i<openFileDialog2.FileNames.Length;i++)
{
listFilesToProtect.Items.Add(openFileDialog2.FileNames[i]);
}
}
}
}
private void btnLoad2_Click(object sender, System.EventArgs e)
{
posX = int.Parse(textBox1.Text);
posY = int.Parse(textBox2.Text);
// heightBackImage = int.Parse(textBox3.Text);
// widthBackImage = int.Parse(textBox4.Text);
if (listFilesToProtect.Items.Count>0)
{
foreach(object it in listFilesToProtect.Items)
{
MergeImages(it.ToString(), txtFileProtector.Text);
}
}
}
You didn't show us at which line this exception is thrown, So I am going to guess here. This error usually occurs when the path of the image that you are trying to load/save is not correct, so check the path for both ImageBack and ImageFore.
Also make sure that the file you are trying to load/save to is not open by another process including your application.
It is worth to mentioned here that you should dispose the images/graphics when you finish from using them, for instance by use using. like
using(Image imgB = Image.FromFile(ImageBack))
{
//the code that is using the imgB here
}