|
Sticking the file in a WebBrowser object won't do what you want?
More detail might be helpful.
|
|
|
|
|
Thanks for the reply! Unfortunately, I'm not allowed to use that. The professor said that I need to write my own code that will parse bold and italic tags and print them accordingly.
|
|
|
|
|
This[^] article may help.
/ravi
|
|
|
|
|
justme89 wrote: The professor said that I need to write my own code that will parse bold and italic tags and print them accordingly.
It depends on what you are supposed to be learning.
If you are learning regex then using that would be the way to go.
If you are learning parsing then you need to build a parser.
If you are learning GUIs then it probably doesn't matter how you parse it.
If you were writing a real application then the real choice is to find a html parser and use it. Or build one if there is some reason you can't find one.
|
|
|
|
|
MMM, as most homework assignments, the mission is a little vague, but here are a few ideas:
1. Make a list of all the tags indicating bold and italic, including a list of corresponding end tags
2
a. either use regex,
b. or StringBuilder class to extract the information from the html file,
c. but why not give a thought as interpreting the html as XML?
if the assignment is only to show the text with an indication for bold and italic, give a thought about removing all the other stuff in a first parsing run (tables, a tags, etc...) and keep the text with the bold/italic tags.
just quick ideas, best of luck.
V.
|
|
|
|
|
V. wrote: why not give a thought as interpreting the html as XML?
because in the majority of web pages the HTML is malformed and not valid XML, e.g. missing a lot of closing tags.
|
|
|
|
|
good point, although it shouldn't, it often is (malformed).
V.
|
|
|
|
|
I have been having some difficulty in a C# application that uses a UDP socket connection. Everything works all sorts of fancy and fun until the closing of my Form application, and then I can't seem to stop receiving messages.
I always get some form of exception inside of the receive callback stating that the socket is disposed. This is, of course, true. The problem is, why am I getting a message after I have closed down and shutdown the sockets? I'm not too familiar with every in and out of C# (don't think I'll ever get used to managed code. Can I have C back?) Included, I have the receive callback, which parses a message and continues to listen. I also included the CloseConnections method, which is called within the Form Closing event.
Does Shutdown and Close not stop the messages from being received? If so, how can I so that the GC may dispose of my sockets without receiving a message afterwards?
"An unhandled exception of type 'System.ObjectDisposedException' occurred in system.dll
Additional information: Cannot access a disposed object named "System.Net.Sockets.Socket"."
private static void ReceiveCallback(IAsyncResult ar)
{
StateObject stateObject = (StateObject)ar.AsyncState;
if(stateObject != null && stateObject.Socket != null && stateObject.DataBuffer != null && stateObject.EventMap != null)
{
int bytesReceived = stateObject.Socket.EndReceive(ar);
if(bytesReceived > 0)
{
SocketConnection.ParseReceiveBuffer(stateObject);
}
}
if(stateObject != null && stateObject.Socket != null && stateObject.DataBuffer != null && stateObject.EventMap != null)
{
stateObject.Socket.BeginReceive(stateObject.DataBuffer, 0, stateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), stateObject);
}
}
public void CloseConnections()
{
if(_recvSocket != null)
{
_recvSocket.Shutdown(SocketShutdown.Both);
_recvSocket.Close();
_recvSocket = null;
_recvState.Socket = null;
_recvState = null;
}
if(_sendSocket != null)
{
_sendSocket.Shutdown(SocketShutdown.Both);
_sendSocket.Close();
_sendSocket = null;
_sendState.Socket = null;
_sendState = null;
}
}
|
|
|
|
|
When you close a Socket I believe any pending asynchronous callbacks are fired to terminate said callbacks. It's by design so it's something you need to handle in your code. When you call EndReceive (or EndAnything for that matter) it can can throw any number of exceptions to indicate failures from the pending operation so those methods should always be wrapped in a try {} catch (stuff) {} block. Basically, anything the synchronous versions of the methods can throw, the asynchronous ones can throw too with some extra ones for good measure. Catching those exceptions is one way that your code could know that it should exit from the callback without initiating another async method call. Another way would be to check a flag in the receive callback that is set in CloseConnections to indicate that work is done.
It also looks like you might be being bit by a lack of thread safety. Async callbacks are executed on Threadpool threads so it's a good bet that CloseConnections and the receive callback are racing to use the socket at the same time. A simple lock(_recvState) { /* use the shared resources here */ } around places where the shared resource are used will be sufficient to protect them.
|
|
|
|
|
Thank you for your reply.
Tossing in some try {} catch {} makes the crash go away, although I do feel a little weird that every run of my application is throwing exceptions in the first place. If I must simply accept the exceptions as a normal operation, then perhaps I must.
I also tried to toss some locks around the state objects on every use. This caused it to hang up inside of the Socket.Shutdown method. I was uncertain as to why exactly, as no breakpoints within any of the other locked locations were hit.
Perhaps simply using a thread-safe static bool will be the way to go. I will let you know if this also helps.
Thank you again for your advice!
|
|
|
|
|
Glad to help
I know you didn't ask for it, but I refactored your snippet into a thread-safe, error handling version as an exercise. I haven't actually run it, but I believe it'll work for you (or at least be close) given that the state object passed as the last parameter to BeginRecieve is _recvState :
private static void ReceiveCallback(IAsyncResult ar)
{
StateObject stateObject = (StateObject)ar.AsyncState;
if (stateObject == null)
{
return;
}
lock (stateObject)
{
if (stateObject.Socket == null)
{
return;
}
int bytesReceived = 0;
try
{
bytesReceived = stateObject.Socket.EndReceive(ar);
}
catch (SocketException)
{
return;
}
catch (ObjectDisposedException)
{
return;
}
if (bytesReceived > 0)
{
SocketConnection.ParseReceiveBuffer(stateObject);
}
stateObject.Socket.BeginReceive(stateObject.DataBuffer, 0, stateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), stateObject);
}
}
public void CloseConnections()
{
lock(_recvState)
{
if (_recvSocket != null)
{
_recvSocket.Shutdown(SocketShutdown.Both);
_recvSocket.Close();
_recvSocket = null;
_recvState.Socket = null;
_recvState = null;
}
}
}
Actually I have to thank you, your original post caused me to go back into some old code and re-look at my own async socket class. Have you ever gone back and looked at something you wrote a long time ago and wondered what was going through your mind when you originally wrote it? I just had one of those moments. It's time for some bug fixing!
|
|
|
|
|
I'm guessing that you have an outstanding call to BeginReceive and calling Close on the Socket . This is probably where you need to research.
I'm also guessing that the reason you're using BeginReceive instead of Receive is because you're running a GUI from this thread and you need to continue to pump messages, right? I've never done this, so I'm not sure what to say. I always try to separate 'View' coding from my 'implementation' coding, so I handle the multithreading like so:
namespace App_Domain
{
class Program
{
static void Main(string[] args)
{
System.Net.Sockets.Socket rec_socket = blah, blah,
send_socket = blah,blah;
System.Threading.Thread rec_pumper = new System.Threading.Thread(
new System.Threading.ParameterizedThreadStart(Pump_Messages));
rec_pumper.Name = "Receive data socket handler";
rec_pumper.Start(rec_socket);
}
public static bool Keep_Running = true;
private const int DATA_LENGTH = 256;
public readonly static Queue<byte[]> _messages = new System.Collections.Generic.Queue<byte[]>();
private static void Pump_Messages(object param)
{
System.Net.Sockets.Socket connected_socket = param as System.Net.Sockets.Socket;
if (connected_socket == null)
throw new System.ArgumentNullException("You must pass a System.Net.Sockets.Socket to me");
byte[] buffer;
while (Keep_Running)
{
if (!connected_socket.Connected)
{
break;
}
if (connected_socket.Available >= DATA_LENGTH)
{
buffer = new byte[DATA_LENGTH];
connected_socket.Receive(buffer);
_messages.Enqueue(buffer);
buffer = null;
}
System.Threading.Thread.Sleep(300);
}
if (connected_socket.Connected)
{
connected_socket.Close();
}
if (Keep_Running)
{
System.Console.WriteLine("Crap! Abnormal termination!! Check the client, he's off his bunker!");
}
}
}
}
I hope this helps.
In Christ,
Aaron Laws
http://ProCure.com
|
|
|
|
|
Thank you for your reply.
You were correct on both of your guesses. I do have an outstanding call to BeginReceive. My problem is that I don't know how to NOT have an outstanding call to BeginReceive. I was under the impression that Socket.Shutdown and Socket.Close were supposed to clear those.
Also, yes I am using this application as a GUI. The form needs to update a DataGrid object fairly constantly in response to socket messages (which is causing a completely different bug that is frustrating me. heh. Am I the only one who misses MFC or Win32 GUI apps? ).
|
|
|
|
|
GrenMeera wrote: You were correct on both of your guesses. I do have an outstanding call to BeginReceive. My problem is that I don't know how to NOT have an outstanding call to BeginReceive. I was under the impression that Socket.Shutdown and Socket.Close were supposed to clear those.
Doesn't really matter. With asynchronous there are two threads and there is no way to insure that an action in thread 1 will only occur at point x in thread 2.
So the close might occur after receiving a message and just as one attempts the reset the BeginReceive.
Mitigation steps can include one or more of the following.
1. Try/catch and experimentation to determine which exceptions are 'normal'
2. A flag that indicates that processing should stop. It should be checked before each action associated with the socket. This flag can also be used to determine the correct handling for exceptions.
3. A message flow that includes a close message - thus BeginReceive would not be reset after this.
|
|
|
|
|
jschell wrote: there is no way to ensure that an action in thread 1 will only occur at point x in thread 2
What do you mean? That's what Monitors, Mutexes, (Manual/Auto)ResetEvents, etc. are for. The other example I posted demonstrates this using lock s. Inside the receive callback the thread waits on the state object until no other thread is in a critical section using the socket. Likewise the Close method waits on the same object until all other threads have left their critical sections that use the socket.
|
|
|
|
|
Dear Sirs,
I'm having a problem with SetWindowsHookEx. In Debug mode, no problem, in release, it throws. Here's the code:
namespace barcode
{
public static class program
{
static void Main(string[] args)
{
_keyboard_delegate = Keyboard_Msg_Pump;
_keyboard_hook_handle = SetWindowsHookEx(
WH_KEYBOARD_LL,
_keyboard_delegate,
System.Runtime.InteropServices.Marshal.GetHINSTANCE(
System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]),
0);
if (_keyboard_hook_handle == 0)
{
int errorCode = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(errorCode);
}
}
private static int Keyboard_Msg_Pump(int nCode, System.Int32 wParam, System.IntPtr lParam)
{
return 12;
}
private static int _keyboard_hook_handle;
private static HOOKPROC _keyboard_delegate;
private delegate int HOOKPROC(int nCode, int wParam, System.IntPtr lParam);
private const int WH_KEYBOARD_LL = 13;
[System.Runtime.InteropServices.DllImport("user32.dll",
CharSet=System.Runtime.InteropServices.CharSet.Auto,
CallingConvention=System.Runtime.InteropServices.CallingConvention.StdCall,
SetLastError=true)]
private static extern int SetWindowsHookEx(
int idHook,
HOOKPROC lpfn,
System.IntPtr hMod,
int dwThreadId);
}
}
If you get to line sixteen (right after the if statement in the Main proc), you have an error. Try stepping through this example and tell me if it works for you. If I'm in debug mode, it works for me, but if I'm in release (even with optimize code off, which I thought would make it just like DEBUG), it fails with inconsistent errors, sometimes it says "Operation completed successfully" sometimes it says "Access denied" and other things. Let me know if you can run it in Release, and how. If not, tell me what error you get.
JUST NOW, as I was writing this, I decided that it might be the setting, "Enable the VSHost" process. If it's off, it works. If it's on, no good. Does the VSHost run under lower authority than the user?? Let me know what you think.
In Christ,
Aaron Laws
http://ProCure.com
|
|
|
|
|
Yep, in order for the keyboard hook to work, you have to turn off the VS Hosting process. I don't know why - you just do. I also don't have any documentation on this. I'm just speaking from my own experience.
|
|
|
|
|
Hi , have a good day
Can anyone Explain for me what the meaning of this ?
a = b == null ? null : a.ToString();
P.S : for more information :
I use this component Example Code , and I need to understand it !
http://www.gemboxsoftware.com/help/html/M_GemBox_Spreadsheet_ExcelWorksheet_ExtractToDataTable.htm[^]
if (e.ErrorID == ExtractDataError.WrongType)
{
e.DataTableValue = e.ExcelValue == null ? null : e.ExcelValue.ToString();
e.Action = ExtractDataEventAction.Continue;
}
Please , Don't tell to Ask at Component Forum , due my question is C# syntax things
thank you
I know nothing , I know nothing ...
|
|
|
|
|
It means
if (b == null)
a = null;
else
a = a.ToString();
But it's an expression instead of a statement.
|
|
|
|
|
Thank you so much , for this fast , great replay of yours ,
you saved me from headache
I have voted for you
I know nothing , I know nothing ...
|
|
|
|
|
Thanks
|
|
|
|
|
And yes I meant b.toString();
I know nothing , I know nothing ...
|
|
|
|
|
everything you should know about C# is in your C# book, in MSDN, in the C# specification[^], etc.
|
|
|
|
|
Thank you ,
But for a certain things MSDN is Yak !
http://msdn.microsoft.com/en-us/library/ty67wk28.aspx[^]
The conditional operator is right-associative. The expression a ? b : c ? d : e is evaluated as a ? b : (c ? d : e), not as (a ? b : c) ? d : e.<br />
<br />
The conditional operator cannot be overloaded.
I know nothing , I know nothing ...
|
|
|
|
|
You're right, and that's classic Microsoft - technically accurate, entirely useless information!
"A Journey of a Thousand Rest Stops Begins with a Single Movement"
|
|
|
|
|