how do i convert these c# winform codes to be compatible on c# wpf? - wpf

hi im working on a project that uses invoke and threads.. it is a simple remote desktop program with chat.. i got a sample here on the internet in c# winform, but i would like to convert it to wpf.. i have no problem in sending message to another client using the wpf program but it cannot receive ( or cannot read) the sent messages from the others.. i think it has something to do with the thread and the invoke method, i read that wpf does invoke differently and i did try the dispatcher.invoke, but it still doesnt do the trick
pls hellp
here's the code
wait = new Thread(new ThreadStart(waitForData));
wait.Start();
that snippet above is executed when a successful connection is made in tcpclient
private void waitForData()
{
try
{
NetworkStream read = tcpclnt.GetStream();
while (read.CanRead)
{
byte[] buffer = new byte[64];
read.Read(buffer, 0, buffer.Length);
s = new ASCIIEncoding().GetString(buffer);
System.Console.WriteLine("Recieved data:" + new ASCIIEncoding().GetString(buffer));
rcvMsg = new ASCIIEncoding().GetString(buffer) + "\n";
hasNewData = true;
bool f = false;
f = rcvMsg.Contains("##");
bool comand = false;
comand = rcvMsg.Contains("*+*-");
/*File receive*/
if (f)
{
string d = "##";
rcvMsg = rcvMsg.TrimStart(d.ToCharArray());
int lastLt = rcvMsg.LastIndexOf("|");
rcvMsg = rcvMsg.Substring(0, lastLt);
NetworkStream ns = tcpclnt.GetStream();
if (ns.CanWrite)
{
string dataS = "^^Y";
byte[] bf = new ASCIIEncoding().GetBytes(dataS);
ns.Write(bf, 0, bf.Length);
ns.Flush();
}
try
{
new Recieve_File().recieve_file(rcvMsg);
}
catch (Exception ec)
{
System.Console.WriteLine(ec.Message);
}
}
/*Command-shutdown/restart/logoff*/
else if (comand)
{
string com = "*+*-";
rcvMsg = rcvMsg.TrimStart(com.ToCharArray());
execute_command(rcvMsg);
}
else
{
this.Invoke(new setOutput(setOut));
Thread.Sleep(1000);
}
}
}
catch (Exception ex)
{
wait.Abort();
output.Text += "Error..... " + ex.StackTrace;
}
}
the snippet above is a code that listens if there is a message or command.. the line
this.invoke(new setoutput(setout)) is a code for appending text in the rtb
hope someone could help me thanks

You've posted a lot of code, but I'm assuming it's only the call to Control.Invoke which is causing the problem. In WPF, use Dispatcher.Invoke (or Dispatcher.BeginInvoke) instead, via the Dispatcher property on the relevant UI element.
I'd also strongly encourage you to:
Refactor your code into smaller methods
Stop catching just Exception except at the top level of any large operation (it should just be a fall-back; usually you catch specific exceptions)
Start following .NET naming conventions
Add a using directive for System so you can just write Console.WriteLine instead of System.Console.WriteLine everywhere
Use Encoding.ASCII instead of creating a new ASCIIEncoding each time you need one
Use a StreamReader to read character data from a stream, instead of reading it as binary data first and then encoding it
For either Stream or TextReader, don't ignore the return value from Read - it tells you how many bytes or characters have been read

Related

how to start console application with windows application and read (monitoring) command line - line by line real time in c#

I have a console application which generating rows line by line:
Data1
Data2
Data3
...
and when its over command line will be cleared, it reapeats infinitelly (the datas can change)
I have to watch the console application's command line with windows aplication real time and work for the lines data (for example save it to list ox line by line)! It is possible?
You basically need to subscribe to the output streams of that console application, to be able to get each line printed on the console.
What you need to do is to create the Windows Forms application (WPF would also work) and start the console application from there.
If you don't want to show your current console application as a visible window, remember to set CreateNoWindow to true.
Here's how to start the console application:
var processStartInfo = new ProcessStartInfo(fileName, arguments);
processStartInfo.UseShellExecute = false;
processStartInfo.ErrorDialog = false;
processStartInfo.RedirectStandardOutput = true; // We handle the output
processStartInfo.CreateNoWindow = true; // If you want to hide the console application so it only works in the background.
// Create the actual process
currentProcess = new Process();
currentProcess.EnableRaisingEvents = true;
currentProcess.StartInfo = processStartInfo;
// Start the process
bool processDidStart = currentProcess.Start();
We need a BackgroundWorker to read the output from the console application in the background.
outputReader = TextReader.Synchronized(currentProcess.StandardOutput);
outputWorker.RunWorkerAsync();
Now you're able to get all the output from the console application in real time and use it to create a list or whatever you want to.
void outputWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Work until cancelled
while (outputWorker.CancellationPending == false)
{
int count = 0;
char[] buffer = new char[1024];
do
{
StringBuilder builder = new StringBuilder();
// Read the data from the buffer and append to the StringBuilder
count = outputReader.Read(buffer, 0, 1024);
builder.Append(buffer, 0, count);
outputWorker.ReportProgress(0, new OutputEvent() { Output = builder.ToString() });
} while (count > 0);
}
}
The processed data is available through the ProgressChanged event of the BackgroundWorker.
void outputWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.UserState is OutputEvent)
{
var outputEvent = e.UserState as OutputEvent;
/* HERE YOU CAN USE THE OUTPUT LIKE THIS:
* outputEvent.Output
*
* FOR EXAMPLE:
* yourList.Add(outputEvent.Output);
*/
}
}
The above code is taken and modified to your purposes from the following Codeproject.com article in case it ceases to exist in the future: Embedding a Console in a C# Application.

Weird incident with DownloadStringAsync

I'm using the following code to download the source code of an HTML page
String search = $"<search url>";
String result = "";
using (WebClient wc = new WebClient())
{
var searchURL = new Uri(search);
wc.DownloadStringCompleted += (s, e) =>
{
result = e.Result;
};
wc.DownloadStringAsync(searchURL);
}
return result.Trim();
This exists in a static method
public static Scrape(String arg)
of a class Scraper.
However, when I do
txtResult.Text = Scraper.Scrape(arg);
in the code behing of a form, nothing appears. Using breakpoints, I see that e.Result indeed contains the expected data, but something happens and the data is "lost" in the way. Anyone has any idea what I'm missing;
Because the download is asynchronous it hasn't updated the value of result before you reach the line return "result.Trim()" as a result you are returning the empty string.
You need to wait for WC to complete, if you use the task method then accessing the result property will cause you to wait for the response.
String search = $"<search url>";
String result = "";
using (WebClient wc = new WebClient())
{
var searchURL = new Uri(search);
result = wc.DownloadStringTaskAsync(searchURL).Result;
}
return result.Trim();
However if you do this in the current method as it stands you will end up hanging your UI as the wait happens on the foreground thread.
You can move the update to the background by changing your call to use a task with a continuation.
Instead of
txtResult.Text = Scraper.Scrape(arg);
Add a using using System.Threading.Tasks;
then you can use the line
Task.Run(() => Scraper.Scrape(arg))
.ContinueWith(t => txtResult.Text = t.Result,
TaskScheduler.FromCurrentSynchronizationContext());
You may also want to precede this with a line txtResult.Text = "Please Wait Fetching....";

Using Database as Alfresco ContentStore

I'm working with Alfresco 4.2 and I need to use a table in my database as document content store.
Collecting some information hither and thither over the internet, I read that I have to just implement my custom DBContentStore DBContentWriter and DBContentReader classes. Someone told me to take as reference the FileContentStore class.
I need some help to mapping the FileContentStore in order to match my new class.
For example;
The DBContentWriter has to extend AbstractContentWriter and in the API docs I read that the only methods I have to overwrite are:
getReader() to create a reader to the underlying content
getDirectWritableChannel() to write content to the repository.
What about the second method?
protected WritableByteChannel getDirectWritableChannel()
This is called by getContentOutputStream():
public OutputStream getContentOutputStream() throws ContentIOException
{
try
{
WritableByteChannel channel = getWritableChannel();
OutputStream is = new BufferedOutputStream(Channels.newOutputStream(channel));
// done
return is;
}
The main method is the putContent(InputStream is) which wants to write content into a DB table.
public final void putContent(InputStream is) throws ContentIOException
{
try
{
OutputStream os = getContentOutputStream();
copyStreams(is, os);
Where copyStreams does something like this:
public final int copyStreams(InputStream in, OutputStream out, long sizeLimit) throws IOException
{
int byteCount = 0;
IOException error = null;
long totalBytesRead = 0;
try
{
byte[] buffer = new byte[BYTE_BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = in.read(buffer)) != -1)
{
// We are able to abort the copy immediately upon limit violation.
totalBytesRead += bytesRead;
if (sizeLimit > 0 && totalBytesRead > sizeLimit)
{
StringBuilder msg = new StringBuilder();
msg.append("Content size violation, limit = ")
.append(sizeLimit);
throw new ContentLimitViolationException(msg.toString());
}
out.write(buffer, 0, bytesRead);
byteCount += bytesRead;
}
out.flush();
}
finally
{
try
{
in.close();
}
catch (IOException e)
{
error = e;
logger.error("Failed to close output stream: " + this, e);
}
try
{
out.close();
}
catch (IOException e)
{
error = e;
logger.error("Failed to close output stream: " + this, e);
}
}
if (error != null)
{
throw error;
}
return byteCount;
}
}
The main target is to write some code in order to write and read from the DB using these methods.
When the out.flush() is called i should have to write into the BLOB field.
thanks
Without looking at the example implementation in FileContentStore it is difficult to determine everything that getDirectWritableChennel() needs to do. Needless to say actually creating a WritableByteChannel to your database should be relatively easy.
Assuming you are using the BLOB type and you are using JDBC to get at your database then you just need to set a stream for your BLOB and turn it in to a channel.
OutputStream stream = myBlob.setBinaryStream(1);
WritableByteChannel channel = Channels.newChannel(stream);
Will you need to overwrite other methods? Maybe. If you have specific issues with those feel free to raise them.

How do I simultaneously read and write to a stream for playing media file in Silverlight 4 MediaStreamSource?

BACKGROUND
I have a media file that I am progressively downloading to my Silverlight 4 application, using WebClient.OpenReadAsync/OpenReadCompleted, and Stream.BeginRead/AsyncCallback. The goal is to play the file in a MediaElement by calling the SetSource method, passing in an instance of our custom MediaStreamSource, so that the file can start playing before the entire contents of the file have been downloaded. The media file is using custom encoding/decoding, which is why we are using a custom MediaStreamSource. Our MediaStreamSource is built to accept a Stream and begin parsing track information and play back in a MediaElement. I have confirmed I am progressively downloading the file contents. Here is a summary of the download code:
public void SetSource(string sourceUrl)
{
var uriBuilder = new UriBuilder(sourceUrl);
WebClient webClient = new WebClient();
// AllowReadStreamBuffering = false allows us to get the stream
// before it's finished writing to it.
webClient.AllowReadStreamBuffering = false;
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
webClient.OpenReadAsync(uriBuilder.Uri);
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
_inboundVideoStream = e.Result;
BeginReadingFromStream();
}
private void BeginReadingFromStream()
{
if (_inboundVideoStream.CanRead)
{
_chunk = new byte[_chunkSize];
_inboundVideoStream.BeginRead(_chunk, 0, _chunk.Length, new AsyncCallback(BeginReadCallback), _inboundVideoStream);
}
}
private void BeginReadCallback(IAsyncResult asyncResult)
{
Stream stream = asyncResult.AsyncState as Stream;
int bytesRead = stream.EndRead(asyncResult);
_totalBytesRead += bytesRead;
if (_playableStream == null)
_playableStream = new MemoryStream();
_playableStream.Write(_chunk, 0, _chunk.Length);
if (!_initializedMediaStream && _playableStream.Length >= _minimumToStartPlayback)
{
_initializedMediaStream = true;
// Problem: we can't hand the stream source a stream that's still being written to
// It's Position is at the end. Can I read and write from the same stream or is there another way
MP4MediaStreamSource streamSource = new MP4MediaStreamSource(_playableStream);
this.Dispatcher.BeginInvoke(() =>
{
mediaElement1.SetSource(streamSource);
});
}
if (_totalBytesRead < _fileSize)
{
ReadFromDownloadStream();
}
else
{
// Finished downloading
}
}
I've tried both writing/reading to a MemoryStream simultaneously, as listed above, as well as writing to an IsolatedStorageFile and reading from that file as I'm writing to it. So far I can't find a way to make either approach work.
QUESTION:
Is there a way to read and write to the same stream? Or is there a standard way to implement this with a stream and MediaStreamSource?
Thanks
The way I did it in my MediaStreamSource implementation is to have 2 streams in it: one for reading and one for writing.
I dispose and re-create the reading stream using the buffer of the writing stream every time GetSampleAsync() is called. Another way to do it I guess is to use a negative offset when creating a MediaStreamSample to pass to ReportGetSampleCompleted() since the position of the stream will always be at the end, but you have to make sure that the position is at the end otherwise this will not work, to keep it simple I just used 2 streams

Large method causing silverlight application to go into "Not responding" state

I am working on an application that plays videos through the silverlight MediaElement object.
I have a large method which is responsible for the following
Opens a FileInfo item on the local file path of the video and strips the file name to get the first portion of the filename which we use as part of the license acquisition process
Sets the LicenseAcquirer on the MediaElement
Sets the Source property of the MediaElement
When this method is called, it actually causes the application to go into a "Not reponding" state for a couple of seconds. How do I avoid this? I have tried putting this all into a background worker but I have to invoke the UI thread for almost all of the calls and this didnt help it seemed to actually make things slower.
I have a busy box that shows while this all happens but that actually stops reporting progress in those seconds where the application is not responding. I understand why this is happening - a lot of work happening on the main UI thread, but how do I avoid this?
This is the code that is causing the trouble:
private void SetupMediaElement(String mediaElementType)
{
Messenger.Default.Send("Loading video...", "SetNowWatchingVideoBusyBoxText");
Messenger.Default.Send(true, "SetNowWatchingVideoBusyBox");
try
{
if (_mainMediaElement != null)
{
VideoItem vi = CurrentSession.NowPlayingVideoItem;
if (vi != null)
{
CurrentVideoItem = vi;
MustShowImage = true;
if (vi.ID != string.Empty)
{
String mediaId = String.Empty;
if (vi.LocalFilePath != DEMOVIDEOPATH)
{
if (vi.LocalFilePath != String.Empty)
{
var fi =
new FileInfo(vi.LocalFilePath);
if (fi.Exists)
{
mediaId = fi.Name.Substring(fi.Name.LastIndexOf('-') + 1,
(fi.Name.LastIndexOf('.') -
(fi.Name.LastIndexOf('-') + 1)));
}
}
else
{
Debug.WriteLine("localFilePath is empty");
}
Debug.WriteLine("MediaId = " + mediaId +
", SessionId = " +
CurrentSession.LoggedOnUser.SessionId +
",Ticket = " +
CurrentSession.LoggedOnUser.Ticket);
string licenseURL = GetLicenseURL(mediaId, CurrentSession.LoggedOnUser.SessionId,
CurrentSession.LoggedOnUser.Ticket);
if (licenseURL != string.Empty)
{
var la = new LicenseAcquirer
{
LicenseServerUriOverride
=
new Uri(
licenseURL)
};
la.AcquireLicenseCompleted += la_AcquireLicenseCompleted;
_mainMediaElement.LicenseAcquirer = la;
}
var fileInfo = new FileInfo(vi.LocalFilePath);
string playURL = #"file://" +
Path.Combine(CoreConfig.HOME_FULL_PATH, fileInfo.Name);
playURL = playURL.Replace("\\", #"/");
VideoURL = playURL;
}
else
{
VideoURL = vi.LocalFilePath;
Messenger.Default.Send(false, "SetNowWatchingVideoBusyBox");
}
_totalDurationSet = false;
TotalTime = FormatTextHoursMinutesSecond(_mainMediaElement.NaturalDuration.TimeSpan);
SetSliderPosition();
}
}
else
{
Messenger.Default.Send(false, "SetNowWatchingVideoBusyBox");
}
}
else
{
Messenger.Default.Send(false, "SetNowWatchingVideoBusyBox");
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
VideoURL = DEMOVIDEOPATH;
Messenger.Default.Send(false, "SetNowWatchingVideoBusyBox");
}
}
Thanks
EDIT:
So it turns out that the method posted above is NOT the cause of the delay - that code executes in under a second. The problem comes in when the media element's source is set and it reads the file to the end - large files take time and this is the delay. Am opening a new question based on this.
You should do some diagnostics to determine which line(s) are truely costing all that time, its unlikely that amount of time is spread evenly across the whole function.
Place that line (or lines) in a background thread (hopefully that line doesn't need to be on the UI thread).
So it turns out that the method posted above is NOT the cause of the delay - that code executes in under a second. The problem comes in when the media element's source is set and it reads the file to the end - large files take time and this is the delay. Am opening a new question based on this.

Resources