Pause and resume a download WPF - c#

Hello I am working on a WPF platform targeting .NET framework 4.5.2. I am writing a downloader for my application. Here is the code:
private void Download(Dictionary<int, FileAndLinkClass> MyLinks)
{
ApplicationDownloadThread = new Thread(() =>
{
foreach (KeyValuePair<int, FileAndLinkClass> item in MyLinks)
{
fileNo++;
WebClient myWebClient = new WebClient();
myWebClient.DownloadProgressChanged += MyWebClient_DownloadProgressChanged;
myWebClient.DownloadFileCompleted += MyWebClient_DownloadFileCompleted;
// Download the Web resource and save it into the current filesystem folder.
string downloadedFileAdress = System.IO.Path.Combine(fileLocation, $"{item.Value.FileName}");
myWebClient.DownloadFileAsync(new Uri(item.Value.Link), downloadedFileAdress);
while (myWebClient.IsBusy)
{
}
}
});
ApplicationDownloadThread.IsBackground = false;
ApplicationDownloadThread.Start();
//UnZipAndCreateUpdatePackage(MyLinks);
}
Now I want at button click the download must be paused and at another button click the download must be resumed. I tried working with .set() property of an AutoReset event and .Reset() property of the same but it didn't work.
I need help. My button click code are:
private AutoResetEvent waitHandle = new AutoResetEvent(true);
private void StartDownloadBtn_Click(object sender, RoutedEventArgs e)
{
waitHandle.Set();
}
private void StopDownloadBtn_Click(object sender, RoutedEventArgs e)
{
waitHandle.Reset();
}
I have also tried this link How to pause/suspend a thread then continue it?. nothing happens
I've also gone through Adding pause and continue ability in my downloader but I failed to incorporate the solution in my above code as I am also updating the download progress on the UI.

Well I did some more digging, apparently if for you Adding pause and continue ability in my downloader wasn't clear as the it uses byte stream data in the class. Maybe you could check out the link below, it also provides a VS solution on WPF for the downloading .zip file extensions with pause/resume/stop capabilities. Please let me know if you need some more help.
Link to CodeProject article:
C# .NET Background File Downloader

Related

WebClient DownloadFileCompleted event not being called in the last item

I Have a large file downloader (about 3GB) full working in almost all devices I tested it. But it some devices the download bar allways gets stuck in 99% (cannot verify this, but seems that is something related with old Win 7 versions). The download works fine, and if I restart the downloader, it shows me that the download is OK, but I cannot tell my clients to restart the downloader if it gets stuck in 99%, so I will appreciate a lot some help on this.
This is the code:
using (_wc = new WebClient())
{
_wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
_wc.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
_wc.DownloadFileAsync(new Uri(fileToDownloadLink), PathToSaveFile);
}
And the event:
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
MessageBox.Show("This box is being called every time except the last one");
}

Pass String from python script to C# UI [duplicate]

I'm making a program that controls a game server. One of the functions I'm making, is a live server logfile monitor.
There is a logfile (a simple textfile) that gets updated by the server as it runs.
How do I continuously check the logfile and output it's content in a RichTextBox?
I did this simple function just try and get the content of the log. It will of course just get the text row by row and output it to my textbox. Also it will lock the program for as long as the loop runs, so I know it's useless.
public void ReadLog()
{
using (StreamReader reader = new StreamReader("server.log"))
{
String line;
// Read and display lines from the file until the end of the file is reached.
while ((line = reader.ReadLine()) != null)
{
monitorTextBox.AppendText(line + "\n");
CursorDown();
}
}
}
But how would you go about solving the live monitoring as simple as possible?
*** EDIT ***
I'm using Prescots solution. great stuff.
At the moment I'm using a sstreamreader to put the text from the file to my textbox. I ran into the problem is that, whenever I tried to access any of the gui controls in my event handler the program just stopped with no error or warnings.
I found out that it has to do with threading. I solved that like this:
private void OnChanged(object source, FileSystemEventArgs e)
{
if (monitorTextField.InvokeRequired)
{
monitorTextField.Invoke((MethodInvoker)delegate { OnChanged(source, e); });
}
else
{
StreamReader reader = new StreamReader("file.txt");
monitorTextField.Text = "";
monitorTextField.Text = reader.ReadToEnd();
reader.Close();
CursorDown();
}
}
Now my only problem is that the file.txt is used by the server so I can't access it, since it's "being used by another process". I can't control that process, so maybe I'm out of luck.
But the file can be opened in notepad while the server is running, so somehow it must be possible. Perhaps I can do a temp copy of the file when it updates and read the copy. I don't know.
Check out the System.IO.FileSystemWatcher class:
public static Watch()
{
var watch = new FileSystemWatcher();
watch.Path = #"D:\tmp";
watch.Filter = "file.txt";
watch.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite; //more options
watch.Changed += new FileSystemEventHandler(OnChanged);
watch.EnableRaisingEvents = true;
}
/// Functions:
private static void OnChanged(object source, FileSystemEventArgs e)
{
if(e.FullPath == #"D:\tmp\file.txt")
{
// do stuff
}
}
Edit: if you know some details about the file, you could handle the most efficent way to get the last line. For example, maybe when you read the file, you can wipe out what you've read, so next time it's updated, you just grab whatever is there and output. Perhaps you know one line is added at a time, then your code can immediately jump to the last line of the file. Etc.
Although the FileSystemWatcher is the most simple solution I have found it to be unreliable in reality.. often a file can be updated with new contents but the FileSystemWatcher does not fire an event until seconds later and often never.
The only reliable way I have found to approach this is to check for changes to the file on a regular basis using a System.Timers.Timer object and checking the file size.
I have written a small class that demonstrates this available here:
https://gist.github.com/ant-fx/989dd86a1ace38a9ac58
Example Usage
var monitor = new LogFileMonitor("c:\temp\app.log", "\r\n");
monitor.OnLine += (s, e) =>
{
// WARNING.. this will be a different thread...
Console.WriteLine(e.Line);
};
monitor.Start();
The only real disadvantage here (apart from a slight performance delay caused by file size checking) is that because it uses a System.Timers.Timer the callback comes from a different thread.
If you are using a Windows Forms or WPF app you could easily modify the class to accept a SynchronizingObject which would ensure the event handler events are called from the same thread.
As #Prescott suggested, use a FileSystemWatcher. And make sure, you open the file with the appropriate FileShare mode (FileShare.ReadWrite seems to be appropriate), since the file might still be opened by the server. If you try to open the file exclusively while it is still used by another process, the open operation will fail.
Also in order to gain a bit of performance, you could remember the last position up to which you already have read the file and only read the new parts.
Use this answer on another post c# continuously read file.
This one is quite efficient, and it checks once per second if the file size has changed.
You can either run it on another thread (or convert to async code), but in any case you would need to marshall the text back to the main thread to append to the textbox.
Try adding a Timer and have the Timer.Tick set to an Interval of 1 second. On Timer.Tick you run the function.
private void myTimer_Tick(object sender, EventArgs e)
{
ReadLog();
}

how can you get a server callback on windows phone 8

I simply want to be able to make a callback on a function in the windows phone code from the server side when something is being updated there. Examples abound on the Internet make use of wsDualHttpBinding, but some wise man has decided to remove support for that from the windows store application API list. I can't find any other way to get the same functionality, does anybody know how to do this?
The reasoning behind not allowing for internet based callbacks is that it puts a big drain on the phone's battery to be constantly listening for them. Instead, they allow you to run PeriodicTask's that will let you occasionally call a server to poll whether there is a change.
Alternatively you could use their notification service:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff402558%28v=vs.105%29.aspx
You can try something like this
System.Net.WebClient wc = new System.Net.WebClient();
public void Initialize(object sender, EventArgs e)
{
wc.DownloadStringCompleted += new System.Net.DownloadStringCompletedEventHandler(done);
}
public string version = "1.0.0";
public void done(object sender, System.Net.DownloadStringCompletedEventArgs e)
{
if (version != e.Result)
{
//Do your code here
}
}
You can create a place online that stores the current version then check on start up.

Task Scheduler using C# (To Schedule .bat(batch) file)

I want to create one Task Scheduler using C# same as Windows Task Scheduler, to run my .bat (batch) file on particular time.
I found this useful link (http://www.codeproject.com/Articles/38553/TaskScheduler)
in this they schedule trigger, and i want to Schedule my .bat file
I mean while i am trying to give my batch file path in tags textbox, its just fired trigger, not run my batch file
so, i modify that code little bit, and now I am able to run my batch file also,
but, when i close my application triggering also stop,
so, is there any way i can triggering or run my batch file even if i close my application liks window task scheduler???
kindly Help me .
Note: its desktop application using C#
you can place the path of your batch file in tags textbox .Checkbox the Active in one time only box ,set the time and at that time the trigger is fired.
Note: It justs fire's the trigger.What you are loking is to run the batch file.In that case you need to modify the code. you can start from
private void buttonCreateTrigger_Click(object sender, EventArgs e)
{
CreateSchedulerItem();
}
in Demo.cs page
In order to run your batch file or exe in TaskScheduler.cs find and replace this code
void _triggerTimer_Tick(object sender, EventArgs e)
{
_triggerTimer.Stop();
foreach (TriggerItem item in TriggerItems)
if (item.Enabled)
while (item.TriggerTime <= DateTime.Now)
item.RunCheck(DateTime.Now);
System.Diagnostics.Process.Start("Your Path");
_triggerTimer.Start();
}
Now you can save this path in some knid of common class and make it access to both.
So, what's the problem? After downloading you can check the Demo.cs, where you can find the method private void CreateSchedulerItem() and the event triggerItem_OnTrigger. You can change this event to run the batch file that you need.
Something like this. I hope that you can change Console.WriteLine on System.Diagnostics.
static void Main(string[] args) {
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
Timer timer = new Timer(PrintHello, autoResetEvent, 0, 5000);
autoResetEvent.WaitOne();
}
private static void PrintHello(Object state) {
Console.WriteLine("Hello");
}

Possible to download a file via WebKit browser in C# using webkitdotnet?

I'm using WebKitDotNet to simulate and automate a web browser. This is really nifty and works in most respects. However, when I try to implement this code, WebKit doesn't trigger a download:
WebKitBrowser _b = null;
private void button1_Click(object sender, EventArgs e)
{
_b = new WebKitBrowser();
_b.DownloadBegin += new FileDownloadBeginEventHandler(b_DownloadBegin);
_b.Error += new WebKitBrowserErrorEventHandler(_b_Error);
_b.AllowDownloads = true;
_b.Navigate("http://sourceforge.net/projects/webkitdotnet/files/WebKit%20.NET%200.x/0.5/WebKit.NET-0.5-bin-cairo.zip/download");
}
void _b_Error(object sender, WebKitBrowserErrorEventArgs e)
{
MessageBox.Show("error!");
}
void b_DownloadBegin(object sender, FileDownloadBeginEventArgs e)
{
MessageBox.Show("hi");
}
Neither the "Error" nor the "DownloadBegin" events fire. I would expect at least one of them to do so - is there a setting that I'm missing?
EDIT: I know this is an old question, but here's the update. When I wrote this question, I was trying to automate a process that required a human being - once per day - to log onto a website, provide credentials, and click a download link. We were hoping to be able to do this programmatically to relieve the monotony for the poor person tasked with doing this job.
Unfortunately, WebKitDotNet did not succeed in this task. Although, in a webkit based browser, you can click on the link and trigger a download, in the embedded WebKitDotNet clicking on the link did nothing. My guess is that something within WebKitDotNet lost the event. If anyone wants to test this, you can use the Sourceforge download link to test.
One of the guys on my team did eventually solve this problem by using an Internet Explorer automation tool called "IMacros". We selected this product because 1) We could guarantee that IE was installed on every computer that would run the program, and 2) IMacros could correctly receive the event from the website and trigger the file download.
On the Issue tracker there is a post date from March 24, 2011 in which is stated that download does not work yet:
https://github.com/webkitdotnet/webkitdotnet/issues/7
Since there are few issues in the tracker, it would have probably been marked as resolved if the feature was added meantime.

Categories

Resources