I've got this code at the start of the form that reads a file that already exists and sets value of 4 textBoxes accordingly to what it's written inside. How do I proceed if the file hasn't yet been created? Any help would be very appreciated.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
FileStream file = new FileStream("cenaEnergentov.txt", FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(file);
sr.ReadLine();
var textLines = File.ReadAllLines("cenaEnergentov.txt");
foreach (var line in textLines)
{
string[] dataArray = line.Split(';');
textBox1.Text = (dataArray[0]);
textBox2.Text = (dataArray[1]);
textBox3.Text = (dataArray[2]);
textBox4.Text = (dataArray[3]);
}
}
If the uper is a false I'd like to proceed with normal script down below that starts with:
public void trackBar1_Scroll(object sender, EventArgs e)
{
......
Use a simple if statement
// I edit this line according to your comment
if(File.Exists(String.Concat("cenaEnergentov".ToUpper(), ".txt"))
{
// do your job
}
else
{
// call appropriate method
trackBar1_Scroll(this,EventArgs.Empty); // for example
}
Try this before you open the file:
var filename = "filename.txt";
if (!File.Exists(filename))
{
File.Create(filename);
}
This won't account for the fact that you're assigning values without checking to see if they exist first. Implementing that is relatively trivial as well.
It also appears that the FileStream and StreamReader are redundant. Just use File.ReadAllLines instead.
The previous solutions will work OK... however they don't really answer the big question:
How do I know when to continue?
The best way would be to use a FileSystemWatcher:
var watcher = new FileSystemWatcher(path, ".txt");
watcher.Created += (sender, e) =>
{
if (e.ChangeType == WatcherChangeTypes.Created)
initForm();
};
Where initForm() is:
void initForm()
{
if(File.Exists(path))
{
// Update form
}
else
{
var watcher = new FileSystemWatcher(path, ".txt");
watcher.Created += (sender, e) =>
{
if (e.ChangeType == WatcherChangeTypes.Created)
initForm();
};
}
}
try this
if(File.Exists("yourFile.txt"))
{
//do what you do
}
else
{
// call appropriate method
}
Related
StreamReader sr = new StreamReader("C:/CR EZ Test/Log.txt"); //use with IF
private void timer2_Tick(object sender, EventArgs e)
{
if ((line = sr.ReadLine()) != null)
{
//FileStream fs = File.Open("C:/CR EZ Test/Log.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
//StreamReader sr = new StreamReader(fs); //use with While can't use with }else{
//while ((line = sr.ReadLine()) != null)
//{
string[] dataLog = line.Split(new[] { ',' }, StringSplitOptions.None);
mpa = (dataLog[1]);
ml = (dataLog[2]);
lph = (dataLog[3]);
elapsedTime = float.Parse(dataLog[4]) / 1000;
if (testStatus > 0) time = elapsedTime.ToString("0.0");
tb2.Value = int.Parse(dataLog[6]);
if (chart1.Series[0].Points.Count > tb1.Value && tb1.Value > 0)
{
chart1.Series[0].Points.RemoveAt(0);
chart1.Series[1].Points.RemoveAt(0);
}
chart1.Series[0].Points.AddXY(dataLog[5], int.Parse(dataLog[1]));
chart1.Series[1].Points.AddXY(dataLog[5], int.Parse(dataLog[6]));
//}
}
else
{
sr.DiscardBufferedData();
sr.BaseStream.Seek(0, SeekOrigin.Begin);
sr.BaseStream.Position = 0;
//sr.Close();
//alertTB.Text = "";
timer2.Enabled = false;
}
alertTB.ForeColor = Color.Red;
alertTB.Text = "Data Log Viewing In Progress";
}
The issue is I am reading a text file full of variables back through a GUI, like replaying a video. As the code is shown, it works and I can control the timer tick to change the replay speed. The issue is the file is in use, so I can't write to or delete the text while the file is in use, without closing it first. I would like to either be able to find a workaround of the Streamreader, or use the Filestream to Streamreader code that will allow me to edit the file while it is in use. The issue there is, I can't figure out how to make it work with the timer, it just reads the entire file very quickly. Any help or ideas are greatly appreciated.
The issue here is how to have the commented out code to:
read a line of the text file,
have the timer to tick
then read the next line of the text file, and so on. Obviously handling the data as it arrives.
Opening a file while it is in use
I think what you are looking for is FileStream with FileShare.ReadWrite for the instance of your StreamReader (not the instance you have commented out),
var fs = new FileStream("C:\foo.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
var sr = new StreamReader(fs);
Setting the position of the stream
It also seems like based on your comments, you are having trouble with positioning the stream, this is how you could do that...
fs.Position = 0; // note this is the FileStream not the StreamReader!
// alternatively, you could use Seek
Difference between sequential and random access
Lastly, you might want to take a look below to see the difference between sequential and random access
A Potential Solution
Here is a class called FileMonitor that will check the file and update the list whenever the file is changed / updated.
I understand that you want a timer to poll the data in the text file, but in case the timer is very fast, I have optimized the FileMonitor to watch the file for changes and only extract when there is a change.
Please note that this only continues to read where it was left off, based on the position of the stream. So, it will not work if lines are deleted or modified prior to getting "extracted". This means it only functions based on your requirements and is not improved to handle a lot of other scenarios, but it should adequately cover your requirements.
public class FileMonitor : IDisposable
{
private readonly FileStream _file;
private readonly StreamReader _reader;
private long _position;
private List<string> _lines;
public FileMonitor(string file)
{
if (String.IsNullOrEmpty(nameof(file))) throw new ArgumentNullException(nameof(file));
_lines = new List<string>();
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = Path.GetDirectoryName(file);
watcher.Filter = Path.GetFileName(file);
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Changed += new FileSystemEventHandler(OnChanged);
//watcher.Created += new FileSystemEventHandler(OnCreated);
//watcher.Deleted += new FileSystemEventHandler(OnDeleted);
//watcher.Renamed += new RenamedEventHandler(OnRenamed);
// begin watching.
watcher.EnableRaisingEvents = true;
// begin reading
_file = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
_reader = new StreamReader(_file);
_lines = ReadLines(_reader).ToList();
_position = _file.Position;
}
private void OnChanged(object source, FileSystemEventArgs e)
{
List<string> update = ReadLines(_reader).ToList();
// fix to remove the immidate newline
if (update.Count() > 0 && String.IsNullOrEmpty(update[0])) update.RemoveAt(0);
_lines.AddRange(update);
_position = _file.Position;
// just for debugging, you should remove this
Console.WriteLine($"File: {e.FullPath} [{e.ChangeType}]");
}
public IEnumerable<string> Lines { get { return _lines; } }
public void Reset()
{
_file.Position = 0;
_position = _file.Position;
_lines.Clear();
}
private static IEnumerable<string> ReadLines(StreamReader reader)
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
public void Dispose()
{
_reader.Dispose();
_file.Dispose();
}
}
Here is how you could use it with your timer
private IEnumerable<string> _lines; // holds all the lines "extracted"
void Main()
{
string file = #"C:\Data\foo.txt";
using (var timer = new System.Timers.Timer())
{
timer.Interval = 2000; // 2 second interval
timer.Elapsed += OnTimedEvent; // attach delegate
timer.Enabled = true; // start the timer
// open the file
using (var monitor = new FileMonitor(file))
{
_lines = monitor.Lines;
// loop forever, remove this
while (true) { }
}
}
}
public void OnTimedEvent(object sender, EventArgs e)
{
// just for debugging, you should remove this
Console.WriteLine($"current count: {_lines.Count()}");
}
If it isn't clear, the data extracted is held in a list of strings. Above, you can grab the "extracted" data from the monitor using the monitor.Line property.
A Proven Working Solution
string line;
if (!File.Exists(logFile))
{
viewLog.Text = "Play";
alertTB.ForeColor = Color.Red;
alertTB.Text = "File Does Not Exist | Log Data To Create File";
chart.Text = "Scope On";
}
if (File.Exists(logFile))
{
var lineCount = File.ReadLines(logFile).Count();//read text file line count to establish length for array
if (lineCount < 2)
{
viewLog.Text = "Play";
alertTB.ForeColor = Color.Red;
alertTB.Text = "File Exists | No Data Has Been Recorded";
chart.Text = "Scope On";
}
if (counter < lineCount && lineCount > 0)//if counter is less than lineCount keep reading lines
{
line = File.ReadAllLines(logFile).Skip(counter).Take(lineCount).First();
string[] dataLog = line.Split(new[] { ',' }, StringSplitOptions.None);
//-----------------------------------------Handling my data
counter++;
}
else
{
counter = 0;
timer2.Enabled = false;
}
}
This is the fix I arrived at, it allows editing the file or deleting the contents of the file. I get the line count before trying to load the file. I then use the counter to iterate through the lines. I can change the delay between the next line read based upon the timer tick interval, pause it, or stop it.
The code that I have included below successfully writes to a CSV file. But if the CSV file that I am writing to happens to be open in Excel, I get a System.IO.Exception that indicates that "the file is being used by another process."
How can I change my code so that the program will continuing running and wait until the CSV is no longer open in Excel?
private void timer1_Tick(object sender, EventArgs e)
{
int actmonth, actyear, actsecond;
System.DateTime fecha = System.DateTime.Now;
actmonth = fecha.Month;
actyear = fecha.Year;
if (actmonth <= 9)
{
valorfechaact = System.Convert.ToString(actyear) + "00" + System.Convert.ToString(actmonth);
}
else
{
valorfechaact = System.Convert.ToString(actyear) + "0" + System.Convert.ToString(actmonth);
}
actsecond = fecha.Second;
string label;
label = label1.Text;
string at = "#";
string filename = valorfechaact + ".csv";
string ruta3 = System.IO.Path.Combine(at, label, filename);
if (Directory.Exists(label1.Text))
{
StreamWriter wr = new StreamWriter(ruta3, true);
wr.WriteLine("1asd" + actsecond);
wr.Close();
wr.Dispose();
}
else
{
System.Console.WriteLine("no se puede escribir en el archivo");
timer1.Stop();
}
}
You can write a Methode which try to open the File with a FileStream and return a boolean Flag
A possible Solution is
public static class FileInfoExtension
{
public static bool IsLocked(this FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
stream?.Close();
}
return false;
}
}
Then you can use it
var fileInfo = new FileInfo(ruta3);
if (!fileInfo.IsLocked())
{
// do code
}
A very simple (and bad) Solution to wait is
while (file.IsLocked())
{
Thread.Sleep(100);
}
General is your Code unclear and difficult to read.
You have much redudant code and few variable are bad named.
Maybe this Guidline can help you https://github.com/dennisdoomen/CSharpGuidelines
Maybe a little bit clearer solution is
private void timer1_Tick(object sender, EventArgs e)
{
var directory = label1.Text;
if (!Directory.Exists(directory))
{
Console.WriteLine("no se puede escribir en el archivo");
timer1.Stop();
return;
}
var now = DateTime.Now;
_valorfechaact = now.Month <= 9 ? $"{now.Year}00{now.Month}" : $"{now.Year}0{now.Month}";
var fullname = Path.Combine("#", directory, $"{_valorfechaact}.csv");
var fileInfo = new FileInfo(fullname);
if (fileInfo.IsLocked())
{
Console.WriteLine($"The File {fullname} is locked!");
return;
}
using (var wr = new StreamWriter(fullname, true))
{
wr.WriteLine("1asd" + now.Second);
}
}
You could take a look at this question:
Checking if an Excel Workbook is open
One of the approaches that are discussed is to simply attempt to access the file. If that throws an exception, you can wait and try again.
If you really want to wait until the workbook is writable you can do that, e.g. by using a while loop (probably you'll want to add a time out, or if relevant alert the user that he/she needs to close the file in Excel).
In code it could be something like:
int someLargeNumberOfIterations = 100000000;
while(FileIsLocked(filepath) && elapsedMs < timeoutMs) {
Thread.SpinWait(someLargeNumberOfIterations);
// Set elapsed
}
// Write the file
where FileIsLocked is a function you write based on the aforementioned post and timeoutMs is some appropriate timeout.
My issue is that I keep seeing a recurring theme with trying to allow my Notepad clone to save a file. Whenever I try to save a file, regardless of the location on the hard disk, the UnauthorizedAccess Exception continues to be thrown. Below is my sample code for what I've done, and I have tried researching this since last night to no avail. Any help would be greatly appreciated.
//located at base class level
private const string fileFilter = "Text Files|*.txt|All Files|*.*";
private string currentPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
private void MenuFileSaveAs_Click(object sender, RoutedEventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.DefaultExt = "*.txt";
sfd.Filter = fileFilter;
sfd.AddExtension = true;
sfd.InitialDirectory = currentPath;
sfd.RestoreDirectory = true;
sfd.OverwritePrompt = true;
sfd.ShowDialog();
try
{
System.IO.File.WriteAllText(currentPath,TxtBox.Text,Encoding.UTF8);
}
catch (ArgumentException)
{
// Do nothing
}
catch(UnauthorizedAccessException)
{
MessageBox.Show("Access Denied");
}
}
Change the following lines.
...
if (sfd.ShowDialog() != true)
return;
try
{
using (var stream = sfd.OpenFile())
using (var writer = new StreamWriter(stream, Encoding.UTF8))
{
writer.Write(TxtBox.Text);
}
}
...
I hope it helps you.
You need to get the correct path context and file object from the dialog box once the user has hit 'ok'. Namely verify the user actually hit ok and then use the OpenFile property to see what their file selection is:
if (sfd.ShowDialog.HasValue && sfd.ShowDialog)
{
if (sfd.OpenFile() != null)
{
// convert your text to byte and .write()
sfd.OpenFile.Close();
}
}
I am using this code to import text file to my ListBox
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files|*.txt";
openFileDialog1.Title = "Select a Text file";
openFileDialog1.FileName = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string file = openFileDialog1.FileName;
string[] text = System.IO.File.ReadAllLines(file);
foreach (string line in text)
{
listBox2.Items.Add(line);
}
listBox2.Items.Add("");
}
It works fine for small text files, with 10 lines or so, but when I try to import bigger list, (4-5 megabytes) the program isn't responding and it's crashing.
Any help?
Use the BufferedStream class in C# to improve performance.
http://msdn.microsoft.com/en-us/library/system.io.bufferedstream.aspx
By using this:
string[] text = System.IO.File.ReadAllLines(file);
listBox1.Items.AddRange(text);
instead of this:
string[] text = System.IO.File.ReadAllLines(file);
foreach (string line in text)
{
listBox2.Items.Add(line);
}
you will speed up the execution at least 10-15 times because you are not invalidating listBox on every Item insert.
I have measured with few thousand lines.
The bottleneck could also be ReadAllLines if your text has too many lines. Even though I can't figure out why you would be inserting so many lines, will user be able to find the line he/she needs?
EDIT OK then I suggest you to use BackgroundWorker, here is the code:
First you initialize BackGroundWorker:
BackgroundWorker bgw;
public Form1()
{
InitializeComponent();
bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
}
Then you call it in your method:
private void button1_Click(object sender, EventArgs e)
{
if (!bgw.IsBusy)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files|*.txt";
openFileDialog1.Title = "Select a Text file";
openFileDialog1.FileName = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string file = openFileDialog1.FileName;
listView1.BeginUpdate();
bgw.RunWorkerAsync(file);
}
}
else
MessageBox.Show("File reading at the moment, try later!");
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
listView1.EndUpdate();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
string fileName = (string)e.Argument;
TextReader t = new StreamReader(fileName);
string line = string.Empty;
while ((line = t.ReadLine()) != null)
{
string nLine = line;
this.Invoke((MethodInvoker)delegate { listBox1.Items.Add(nLine); });
}
}
It will add each line when it reads it, you will have responsive UI, and lines won't affect the listBox before it finishes loading.
It maybe simply not completing its job, and you should have to wait for more. Try with this solution:
http://www.bytechaser.com/en/articles/f3a3niqyb7/display-large-lists-in-listview-control-quickly.aspx
could use a stream to store the data:
class Test
{
public static void Main()
{
string path = #"c:\temp\MyTest.txt";
//Create the file.
using (FileStream fs = File.Create(path))
{
AddText(fs, "This is some text");
AddText(fs, "This is some more text,");
AddText(fs, "\r\nand this is on a new line");
AddText(fs, "\r\n\r\nThe following is a subset of characters:\r\n");
for (int i=1;i < 120;i++)
{
AddText(fs, Convert.ToChar(i).ToString());
}
}
//Open the stream and read it back.
using (FileStream fs = File.OpenRead(path))
{
byte[] b = new byte[1024];
UTF8Encoding temp = new UTF8Encoding(true);
while (fs.Read(b,0,b.Length) > 0)
{
Console.WriteLine(temp.GetString(b));
}
}
}
private static void AddText(FileStream fs, string value)
{
byte[] info = new UTF8Encoding(true).GetBytes(value);
fs.Write(info, 0, info.Length);
}
}
then you event handler
privateasyncvoid Button_Click(object sender, RoutedEventArgs e)
{
UnicodeEncoding uniencoding = new UnicodeEncoding();
string filename = #"c:\Users\exampleuser\Documents\userinputlog.txt";
byte[] result = uniencoding.GetBytes(UserInput.Text);
using (FileStream SourceStream = File.Open(filename, FileMode.OpenOrCreate))
{
SourceStream.Seek(0, SeekOrigin.End);
await SourceStream.WriteAsync(result, 0, result.Length);
}
}
Your application becomes unresponsive because it's waiting for the ReadAllLines method to complete and blocks the UI thread. You may want to read files on a separate thread to avoid blocking the UI. I cannot guarantee that the code below will work without errors but it should give you an idea on how to tackle the problem.
First of all, you'll need a method to append an item to the ListBox:
private void AddListBoxItem(string item)
{
if(!InvokeRequired)
{
listBox2.Items.Add(item);
}
else
{
var callback = new Action<string>(AddListBoxItem);
Invoke(callback, new object[]{item});
}
}
The method above checks if it is executed on UI thread and if yes, it simply adds an item to the listBox2.Items collection; if not, it creates a delegate from itself and invokes that delegate on UI thread.
Next, you'll need to move the code that reads the file to another thread and call AddListBoxItem method. For the sake of readability, let's put that into a separate method:
private void AddFileContentsToList(string fileName)
{
using(var reader = new System.IO.StreamReader(fileName))
{
while(!reader.EndOfStream)
{
var line = reader.ReadLine();
AddListBoxItem(line);
}
}
}
And now we will call the method on a separate thread:
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files|*.txt";
openFileDialog1.Title = "Select a Text file";
openFileDialog1.FileName = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
var thread = new Thread(AddFileContentsToList);
thread.Start();
}
Hope this helps!
I have a collection of picture Objects for which I need to download thumbs and pictures files located on dataservise, how can I managed this?
In this method I have loop to call three methods; one to add objects to data base, second to download and save picture thumb and third to download and save picture file the other two is ClientOpenReadCompleted methods.
public bool AddAllPhoto()
{
var amount = App.ViewModel.NewPictures.Count;
for (int i = 0; i < amount; i++)
{
//to add picture to DB
SavePicture(App.ViewModel.NewPictures[i]);
DownloadPicture(NewPictures[i].ID.ToString());
DownloadPictureThumb(NewPictures[i].ID.ToString()));
}
return true;
}
Second;
public void DownloadPictureThumb(string path)
{
string outputString = String.Format("http://" + App.ServerAdress + "/ /Pictures/Thumbs/{0}.jpg", path);
var client = new WebClient();
client.OpenReadCompleted += ClientOpenReadCompleted1;
client.OpenReadAsync(new Uri(outputString));
}
private static void ClientOpenReadCompleted1(object sender, OpenReadCompletedEventArgs e)
{
var resInfo = new StreamResourceInfo(e.Result, null);
var reader = new StreamReader(resInfo.Stream);
byte[] contents;
using (var bReader = new BinaryReader(reader.BaseStream))
{
contents = bReader.ReadBytes((int)reader.BaseStream.Length);
}
var file = IsolatedStorageFile.GetUserStoreForApplication();
var thumbFilePath = String.Format(PicturesThumbsColectionKey + "{0}", PictureDataStoreLocal.ID);
var stream = thumbFile.CreateFile(thumbFilePath);
stream.Write(contents, 0, contents.Length);
stream.Close();
}
And third one
public void DownloadPicture(string path)
{
string outputString = String.Format("http://" + App.ServerAdress + "/Pictures/{0}.jpg", path);
var client = new WebClient();
client.OpenReadCompleted += ClientOpenReadCompleted1;
client.OpenReadAsync(new Uri(outputString));
}
private static void ClientOpenReadCompleted1(object sender, OpenReadCompletedEventArgs e)
{
var resInfo = new StreamResourceInfo(e.Result, null);
var reader = new StreamReader(resInfo.Stream);
byte[] contents;
using (var bReader = new BinaryReader(reader.BaseStream))
{
contents = bReader.ReadBytes((int)reader.BaseStream.Length);
}
var file = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream stream = file.CreateFile(PictureDataStoreLocal.ID.ToString());
stream.Write(contents, 0, contents.Length);
stream.Close();
}
I assume you want to process the pictures synchronously. If so I would use a wait handle. The easiest way to do this would be to declare a private AutoResetEvent field. The AutoResetEvent is good here because it just lets one thread through and then blocks again automatically.
If you do this you will need to make sure of two things:
1. You do ALL work on a different thread so that when you call WaitOne() you aren't blocking the thread that is supposed to be doing the work.
2. You always reset the wait handle regardless of the outcome of the server calls.
To take care of 1. you just need to update your loop:
m_waitHandle.Reset(); // Make sure the wait handle blocks when WaitOne() is called
for (int i = 0; i < amount; i++)
{
// Process on a background thread
ThreadPool.QueueUserWorkItem((obj) =>
{
// Get the current index. This is an anonymous method so if
// we use 'i' directly we will not necessarily be using the
// correct index. In our case the wait handle avoids this
// problem as the pictures are downloaded one after the other
// but it's still good practise to NEVER use a loop variable in
// an anonymous method.
int index = (int)obj;
//to add picture to DB
SavePicture(App.ViewModel.NewPictures[index]);
DownloadPicture(NewPictures[index].ID.ToString());
DownloadPictureThumb(NewPictures[index].ID.ToString()));
}, i);
m_waitHandle.WaitOne(); // Wait for processing to finish
}
For 2. you need to make sure that m_waitHandle.Set() is ALWAYS called when processing is finished.
What I do is send extra parameters to the OpenReadCompleted event using a delegate like so,
someimage.LoadingCompleted += delegate(object sender, EventArgs imge) { someimage_LoadingCompleted(sender, imge, _item, "someimage"); };
and then in someimage_LoadingCompleted I have code within a switch statement.
Here is my solution, not that elegant but working one; If you have any suggestion to improve , please post and I will edit my post.
EventWaitHandle m_WaitHandle;
public bool AddAllPhoto()
{
var amount = App.ViewModel.NewPictures.Count;
if (m_WaitHandle!=null)
m_WaitHandle.Reset();
for (int i = 0; i < amount; i++)
{
{
SavePicture(App.ViewModel.NewPictures[i]);
ThreadPool.QueueUserWorkItem((obj) =>
{
var index = (int)obj;
DownloadPictureThumb(App.ViewModel.NewPictures[index].ID.ToString());
DownloadPicture(App.ViewModel.NewPictures[index].ID.ToString());
},i);
if (m_WaitHandle != null) m_WaitHandle.WaitOne();
}
return true;
}
public void DownloadPictureThumb(string path)
{
string outputString = String.Format("http://" + App.ServerAdress + "/Pictures/Thumbs/{0}.jpg", path);
var client = new WebClient();
client.OpenReadCompleted += ClientOpenReadCompleted2;
client.OpenReadAsync(new Uri(outputString),path);
}
private static void ClientOpenReadCompleted2(object sender, OpenReadCompletedEventArgs e)
{
var resInfo = new StreamResourceInfo(e.Result, null);
var reader = new StreamReader(resInfo.Stream);
byte[] contents;
using (var bReader = new BinaryReader(reader.BaseStream))
{
contents = bReader.ReadBytes((int)reader.BaseStream.Length);
}
var file = IsolatedStorageFile.GetUserStoreForApplication();
var thumbFilePath = String.Format(PicturesThumbsColectionKey + "{0}", e.UserState as string);
var stream = file.CreateFile(thumbFilePath);
stream.Write(contents, 0, contents.Length);
stream.Close();
}
public void DownloadPicture(string path)
{
string outputString = String.Format("http://" + App.ServerAdress + "/Pictures/{0}.jpg", path);
var client = new WebClient();
client.OpenReadCompleted += ClientOpenReadCompleted1;
client.OpenReadAsync(new Uri(outputString), path);
}
private static void ClientOpenReadCompleted1(object sender, OpenReadCompletedEventArgs e)
{
var resInfo = new StreamResourceInfo(e.Result, null);
var reader = new StreamReader(resInfo.Stream);
byte[] contents;
using (var bReader = new BinaryReader(reader.BaseStream))
{
contents = bReader.ReadBytes((int)reader.BaseStream.Length);
}
var file = IsolatedStorageFile.GetUserStoreForApplication();
var stream = file.CreateFile(e.UserState as string);
stream.Write(contents, 0, contents.Length);
stream.Close();
}
[Here][1] you will find explanation to how to get the url from WebClient in OpenReadCompleted?