private async void Clicked(object sender, RoutedEventArgs e)
{
StorageFolder s;
s = KnownFolders.DocumentsLibrary;
IReadOnlyList<StorageFile> l = await s.GetFilesAsync();
bool exists=false;
foreach (StorageFile sf in l)
{
if (string.Equals(sf.Name, "encrypted.txt", StringComparison.CurrentCultureIgnoreCase))
exists = true;
}
MessageDialog d = new MessageDialog(exists.ToString());
await d.ShowAsync();
}
When debugging the code, I'm not able to step through the code inside the foreach loop
While the value of exists at the end of the loop is correct, and I can see the loop execution if I put the MessageDialog code inside the loop, any idea how to step into the loop properly?
Even when I put the MessageDialog code in the loop, I'm unable to step into the if condition, so I suspect the issue lies somewhere in there
EDIT: Putting a breakpoint on the if condition works (currently I'm putting it on the 1st line of the function), but shouldn't I be able to step into the loop normally using F11 if I'm debugging line by line anyways? (atleast that's how it worked in TurboC)
EDIT2: Easiest way I could think of to show the issue clearly: http://www.youtube.com/watch?v=10GgXCqLlVo&feature=youtu.be (skip to 25 second mark to see the actual issue)
I don't know the details of how debugging works with async methods (I don't tend to use debuggers much), but you need to understand that the system will basically call back into the method, having returned from it (as far as the caller is concerned) when it first reaches an await expression which hasn't already completed.
I would put a break point on the bool exists=false; line, i.e. after the first await expression. You should then be able to use F10 (step over) to iterate through the loop.
Alternatively, you could get rid of the loop entirely using LINQ:
bool exists = l.Any(sf => string.Equals(sf.Name, "encrypted.txt",
StringComparison.CurrentCultureIgnoreCase));
Related
Is there any way to pause the debugging without breakpoints in VS? (c# Console Application)
I noticed that after a few time my program simply stops working but no exception is thrown, it simply stop doing what it should do.
That's why I wanted to know if there is any way i could pause the code as if there was a breakpoint there, so that i would be able to understand what happend.
The program scrapes data from a website and inserts it into a MS SQL SERVER database if it matters.
EDIT :
That's the function that does the magic in my code and scrapes the data from the website. All other things are just data monipulatins.
public static string PostRequest(string url, string request)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = request;
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
return result;
}
}
And again no exception is being thrown.
I asked for no breakpoints because the program runs just fine for the first 500 times. Past that number give or take it freezes.
This line will break as if it were a break point:
System.Diagnostics.Debugger.Break();
Have you considered
Console.ReadLine();
or
Console.ReadKey();
?
You can put a System.Diagnostics.Debugger.Break(); somewhere, with some "activation" condition that can trigger it.
As example, you can have a thread just checking for some condition
As a start, something like this (yes, it can be improved, this is just an idea)
void CheckAndDebugBreak()
{
while (true)
{
string fileGuard = ...; // whatever file you can easily create/delete
if (File.Exists(fileGuard))
{
File.Delete(fileGuard); // to avoid hitting the breakpoint next time, recreate the file if needed
System.Diagnostics.Debugger.Break();
}
// some way to stop the infinite loop e.g.
if (somevariableSetOutside)
break;
// wait a while before next check
System.Threading.Thread.Sleep(1000);
}
}
If you are only avoiding breakpoints because you don't want to have to manually cycle through, you can try this:
Set a break point at the beginning of your function.
Mouse over the breakpoint and select the 'gear' symbol
Check the "Conditions" box
Select "Hit Count" from the first drop down, and set a value
This will stop execution on the breakpoint after that many cycles. So you could run for 500 cycles, then pause at a breakpoint.
Additionally, you can create a Count variable to count the cycles and output the number to the console each cycle to determine exactly how many cycles it makes it through, and if the number is consistent or not.
Select menu Debug - Break All to break into the next available line of code in an executing app. See Navigate Code with the Visual Studio Debugger for more information.
I have a service using WCF. Internally it has a dictionary with lists that you can add to or get a subset of from different endpoints.
The code is something like this:
List<Data> list = null;
try
{
locker.EnterReadLock();
list = internalData[Something].Where(x => x.hassomething()).ToList();
}
finally
{
locker.ExitReadLock();
}
foreach (var y in list)
{
result[y.proprty1].Add(y.property2); // <-- here it hangs
}
return result;
So the internalData is locked with a ReaderWriterLockSlim for all operations, readerlock for reading and writerlock for adding. I make a copy of the items inside the lock and work on this copy later.
The issue is after a while, more and more cpu-cores goes to 100% and finally is uses all cores. It can run perfectly for days and million calls before it stops.
Attaching debugger and pausing shows that one treads hang on adding to the result dictionary. But as soon as I resume all threads will continue and a lot of memory is being released.
Is there something special happening when a debugger is attached, pausing and resuming that will release something like this?
I changed my locks to lock(something) { code... } and the problem with hangs went away. So it looks lilke i ran into the issue Steffen Winkler pointed out in his comment. http://joeduffyblog.com/2007/02/07/introducing-the-new-readerwriterlockslim-in-orcas/
Forgive me if the problem seems obvious. I'm new to programming, started last July. I built a really cool project that prints dozens of Report Types based on a series of Templates. This particular problem happened after I cleaned up some dirty code. I didn't think any changes had been made to these lines.
This line of code worked perfectly before the changes. Now, it seemingly doesn't even open a new process to DoWork().
//For Reference: this is in Main()
var PrintingTask = new Task(csvStatements.PrintStatementPDF);
PrinterThreads.Add(PrintingTask);
Parallel.ForEach(PrinterThreads, t =>
{
t.Start();
});
Task.WaitAll(PrinterThreads.ToArray());
I commented that out, and just ran the job as a method call from csvStatements. So I wrote csvStatements.PrintStatementPDF();
In my code, I print statements to a colored template, but I also print them as just text on a white page (so we can use the last of our special papers we used before, which has the template on them).
That task is written like so:
//For Reference: this is in my csvStatements object from above.
using (StreamReader sr = new StreamReader(csvFile))
{
//2d Array. Left dimension is the page number, Right dimension is the text field number.
var Fields = new System.Collections.Generic.List<List<string>>();
while (!sr.EndOfStream)
{
var Field = sr.ReadLine().Split('\t').ToList();
Fields.Add(Field);
}
var BlankVersion = new PrintBlankStatement();
using (var PrintingTask = new Task(() => BlankVersion.PrintBlankStatementPDF(Fields)))
{
PrintingTask.Start();
//I just added the line below. It wasn't originally there.
await Task.WhenAll(PrintingTask);
}
}
And, while that tasks runs, the program continues to print the statements to the template. So they should run in parallel. But now, when stepping through the project, the first block of code seemingly executes instantaneously (which is absurd, given the 300 pages of pdfs it needs to do) and doesn't actually produce the pdfs. The second block of code somehow also exits the program with code 0 (even though that's something done in Main(), which it shouldn't be able to do).
Did I make some change to these tasks that rendered them useless or is it more likely that the error is elsewhere in my project?
Something tells me this might be a stupid question and I have in fact approached my problem from the wrong direction, but here goes.
I have some code that loops through all the documents in a folder - The alphabetical order of these documents in each folder is important, this importance is also reflected in the order the documents are printed. Here is a simplified version:
var wordApp = new Microsoft.Office.Interop.Word.Application();
foreach (var file in Directory.EnumerateFiles(folder))
{
fileCounter++;
// Print file, referencing a previously instantiated word application object
wordApp.Documents.Open(...)
wordApp.PrintOut(...)
wordApp.ActiveDocument.Close(...)
}
It seems (and I could be wrong) that the PrintOut code is asynchronous, and the application sometimes gets into a situation where the documents get printed out of order. This is confirmed because if I step through, or place a long enough Sleep() call, the order of all the files is correct.
How should I prevent the next print task from starting before the previous one has finished?
I initially thought that I could use a lock(someObject){} until I remembered that they are only useful for preventing multiple threads accessing the same code block. This is all on the same thread.
There are some events I can wire into on the Microsoft.Office.Interop.Word.Application object: DocumentOpen, DocumentBeforeClose and DocumentBeforePrint
I have just thought that this might actually be a problem with the print queue not being able to accurately distinguish lots of documents that are added within the same second. This can't be the problem, can it?
As a side note, this loop is within the code called from the DoWork event of a BackgroundWorker object. I'm using this to prevent UI blocking and to feedback the progress of the process.
Your event-handling approach seems like a good one. Instead of using a loop, you could add a handler to the DocumentBeforeClose event, in which you would get the next file to print, send it to Word, and continue. Something like this:
List<...> m_files = Directory.EnumerateFiles(folder);
wordApp.DocumentBeforeClose += ProcessNextDocument;
...
void ProcessNextDocument(...)
{
File file = null;
lock(m_files)
{
if (m_files.Count > 0)
{
file = m_files[m_files.Count - 1];
m_files.RemoveAt(m_files.Count - 1);
}
else
{
// Done!
}
}
if (file != null)
{
PrintDocument(file);
}
}
void PrintDocument(File file)
{
wordApp.Document.Open(...);
wordApp.Document.PrintOut(...);
wordApp.ActiveDocument.Close(...);
}
The first parameter of Application.PrintOut specifies whether the printing should take place in the background or not. By setting it to false it will work synchronously.
This piece of code keeps throwing a stackoverflow exception and I have a feeling it's either because of the await keyword causing the stack to fill up, or a thread availability issue. However, I'm not sure what the best way of remedying this would be.
The results variable is just a collection of StorageFiles and if it's above 1020 or so, the exception is thrown; otherwise it's usually fine.
private async void GetMusicTest()
{
var sfolder = await StorageFolder.GetFolderFromPathAsync(dir);
var query = sfolder.CreateFileQueryWithOptions(queryOptions);
var results = await query.GetFilesAsync();
for (int i = 0; i < results.Count; i++)
{
MusicProperties mp = await results[i].Properties.GetMusicPropertiesAsync();
Debug.WriteLine(mp.Title);
}
}
This code works fine in a console application, but the error is thrown when used in a desktop WinForm app.
Interestingly, if result.Count() is used instead, then the error is thrown after three iterations, whereas results.Count throws it after iterating through at least half of the collection, if not all (it seems to vary). They both return the same values. What's the best way looping through without causing a stackoverflow exception or using up all available threads?
I think this is a bug that should be addressed.
If I'm right, you can work around it by occasionally doing an await Task.Yield() within your loop.