|
Ok. One more Thing is about using Invoke method.
What i want to achieve is :
1. Read data on Serial port
2. Store it in File over PC (as raw data file)
3. Show data in decoded form over datagridview
So how i can invoke this 3 processes? If i solve this it will be done i guess.
I tried possibility like:
1. Read serialport data using serialport.BytetoRead();
2. Write data in File over PC
Both 1 & 2 i called in serialdataEvent handler
3. Invoke Timer from serialdataevent handler
But its giving me exeption handler error.
|
|
|
|
|
3 threads: 1 for the serial port; 1 for the file writer; and one for the "grid worker".
Create 2 concurrent queues; one for the file writer and one for the grid worker.
Serial reader writes to both queues; and invokes other threads if not "awake" at each queue write.
Workers run until their respective queues are exhausted; and restarted for "new work".
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
When using a worker thread there is no need to user a timer. Read the data and write them to file within the worker thread and then pass the data to the GUI thread (using delegate).
You already use a threaded receive function: port_DataReceived() .
Receive the data there instead of starting a timer.
I'm not very good in C# so I can't provide a full solution.
See for example this QA serial port using threading[^] and Basic serial port listening application[^].
|
|
|
|
|
Hi,
your job is quite a challenge: with loads of data incoming at high rate and no way to stop the producer, the consumer (i.e. your PC program) needs to be designed and coded carefully and economically to obtain an acceptable probability of it keeping up with the producer under normal circumstances.
1. I do agree with what others said about using threads, not timers.
2. I do not like your approach of turning all data into strings, such conversion is time consuming and unnecessary, the one positive thing about it is it is easy and quite readable. If incoming data is binary, you should keep it binary at all times IMO. And your file should be binary too, unless there are forcing reasons against that.
3. Moreover, your code seems to be wasting huge amounts of computer cycles; there are dozens of calls to ByteArrayToHexString(buffer) all performing the same expensive job; and then a lot of them only are interested in a small part of the result, e.g. ByteArrayToHexString(buffer).Substring(16, 8); so why convert everything?
If you insist on having a conversion, either perform it once and store the result, or only convert the part you're interested in (i.e. pass startIndex and Length to the conversion method).
4. As you are basically performing two jobs (display and storage) and missing 30% of the data, it must be hard to figure out exactly where it goes wrong when it does. So I would suggest you concentrate on one job until that works perfectly; then do the other job, and finally combine them.
I hope this helps; I do realize my suggestions may imply a lot of work, and the need for a lot more code.
|
|
|
|
|
Hello,
Thank you for Reply.
- I am now changing my Approach from timers to threads. But i want to update my datagridview suppose at every second. So do i just Need to call datagridview thread in timer?
- I will store the result in string & then use same for Splitting. Basically i am sniffing protocol which have defined structure. So either i can use string Approach or i Need to read & check every Byte to match with my protocol structure. So to avoid this i am just converting them in to string & then Splitting in to substrings.
- I will follow same.
|
|
|
|
|
Hi again,
1. There is no such thing as "calling a thread". Every thread is running all the time, provided it isn't blocked and sufficient CPU resources are available. Thread code often consists of one big loop performing some calculations and then either waiting (=being blocked on some object, say a WaitHandle) or just testing for more work (=polling). When polling, make sure not to have it spin all the time, which means when no job is available, block it for at least a fraction of a second (e.g. with a Thread.Sleep). Best is to use an event-driven approach though.
2. A WinForms Control will try and repaint itself as soon as there is a need for that, e.g. when you scroll it, your code adds/modifies data to it, etc. You can request a repaint by calling its Invalidate() method, which does not guarantee an immediate repaint, it merely queues a request. If you insist on having a periodic repaint, just use a Windows.Forms.Timer and in its Tick handler just do myDGV.Invalidate() ; However, a list Control that gets an item added does not need an explicit Invalidate, it will know a repaint is required all by itself.
3. A DataGridView is a complex and expensive Control, that may require a lot of CPU cycles. If all you need is a way to look at some data, without lots of user interaction, sorting, and the like, I would recommend you use a ListBox instead. And assuming you'll have hundreds of items in it, I would suggest you make it hold your byte arrays, not strings; ListBoxes indeed hold items, not just strings, and allocate a rectangular area for displaying each of those items. If you make it userdrawn (myLB.DrawMode = DrawMode.OwnerDrawFixed; ), and provide a DrawItem handler, you can actually paint whatever you want it to paint inside its rectangle; that allows you to create very inexpensive columns and backgrounds. Finally setting myLB.TopIndex=myLB.Items.Count-1; each time you add an item to it will ensure your ListBox keeps scrolling up automatically.
The nice thing about this approach is you only spend CPU resources to rows that are actually visible, all rows that are off-screen or otherwise invisible will not have their DrawItem event firing.
If all this is new to you, I suggest you read up on ListBox, and maybe this could be a good example.
|
|
|
|
|
Hello,
Thank you for Information. I will go thrigh it.
Meanwhile i was checking my Code with Debugger & i found that before completely reading whole buffer, my Byte Array is taking new Bytes due to which i am losing data.
So somwthing is missing or wrong in this Loop:
private void DoUpdate(object s,EventArgs e)
{<br />
/Read Data coming from ComPort Byte by Byte &store in the buffer/
int Bytes = serialPort1.BytesToRead;
byte[] buffer = new byte[Bytes];
serialPort1.Read(buffer, 0, buffer.Length);
<pre>
result = ByteArrayToHexString(buffer);
for (int i = 0; i <= buffer.Length; i++)
{
processData();
return;
}
}</pre>
I tried using while Loop- (Read==buffer.length) but ist not giving me desired Output. Rather ist copying same data again & again.
I am updating my datagridview in processData().
|
|
|
|
|
Hi,
1. the Visual Studio Debugger isn't very good at dealing with real-time applications, when you set breakpoints and are single-stepping, the whole timing of your code is ruined.
I recommend you use logging instead, please read my article: A simple logging scheme[^].
2. I found a better example for userdrawn listboxes: my article: Asynchronous operations run on ThreadPool threads[^]. The topic itself of that article should be of interest to you too.
3. There might be an issue of the DataReceived handler not always executing on the same thread, and hence, one handler execution possibly overlapping a previous one. That too is touched on in the latter article.
4. As far as your latest code goes, you just can't call processData(); for each and every byte; it is bound to include a task switch (some Invoke or BeginInvoke) and Windows cannot possibly be switching threads at the same pace as your serial data bytes are coming in.
5. It might be useful to tweak the data source for now (if doable), so predictable data is being generated e.g. numbered packets containing a fixed number of incrementing byte values; in my experience that facilitates the debugging a lot as any deviation at the reception side would be noticed quite easily.
In summary, I urge you to rely on logging; to include the thread number in every log message (and check they are acceptable); to have a log message at the start and the end of the DataReceived handler (and more); and to be fully aware of your CPU load. And please drop the DGV, just get the reception of your data solved without wasting time in displaying it; when that works, start solving the display problem, at best with a ListBox.
|
|
|
|
|
So I'm storing some images in a file. I get the bytes, and convert the bytes to a Base64 string, that I place in a model that I return as Json.
At first everything was working fine with test images. Then I started using the customer images and pictures off my iPhone 6 and that's where the trouble began.
I get this parser error on the JQuery side, in which I isolated down to the Base64 string of the image.
So I have some bad chars that need to be formatted or converted.
I'm lost here ....
I have the replace statements that I added, but still get the error.
I think the pad right is not required.
I took the plain base64 string and pasted it into Best Online Base64 to Image converter and the image rendered fine.
I searched for JSON encoding, and got the replace chars.
Any point in the right direction would be appreciated.
picture.Base64 is a string
picture.Data is byte[]
public async Task<JsonResult> json_load_portfolio_picture(int PictureID, string PictureName)
{
model_portfolio_image picture = io_portfolio_images.Load_Portfolio_Picture(PictureID);
if (picture != null )
{
picture.Base64 = Convert.ToBase64String(picture.Data, 0, picture.Data.Length).Replace("/", "-").Replace("+", "_").Replace("=", "");
picture.Base64 = picture.Base64.PadRight(picture.Base64.Length + (4 - picture.Base64.Length % 4) % 4, '=');
}
await Task.Delay(1);
return Json(picture, JsonRequestBehavior.AllowGet);
}
If it ain't broke don't fix it
|
|
|
|
|
Well I had a number of issues that just compounded the problem.
First after I posted the page back with the wrong picture data ( A picture in which I used JavaScript to capture page form data and just converted the selected image to a base64 string and stuffed it in a textbox to postback later), I used the wrong data or bytes to store the image in the database (The original and not the copy). I should of used the bytes from the new Graphic after resizing. This got rid of the iPhone data (EXIF stuff) that was in the image stream. So now my Base64 string starts with that
iVBOR instead of
/9
After that, I searched everywhere on how to UTF8 a Base64 string and could not find anything on the subject. So I created a new JsonResult and set the max limit, content type and encoding and returned that object instead.
[HttpPost]
public async Task<JsonResult> json_load_portfolio_picture(int PictureID, string PictureName)
{
model_portfolio_image picture = io_portfolio_images.Load_Portfolio_Picture(PictureID);
if (picture != null)<br />
picture.Base64 = Convert.ToBase64String(picture.Data, Base64FormattingOptions.None).Trim();
JsonResult jResult = new JsonResult()
{
Data = picture,
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
ContentEncoding = Encoding.UTF8,
MaxJsonLength = 50000000,
ContentType = "application/json"
};
await Task.Delay(1);
return jResult;
}
If it ain't broke don't fix it
|
|
|
|
|
Why have you got await Task.Delay(1); in there?
If it's just to get rid of the "async method lacks await" warning, then it would be simpler to remove the async modifier:
public JsonResult json_load_portfolio_picture(int PictureID, string PictureName)
You don't have any other await calls in the method, so there's no point making it async .
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I knew somebody was going to ask that.
Because it was the minimum requirement to make the task async. But that task really doesn't need to be async since I'm getting information.
If it ain't broke don't fix it
|
|
|
|
|
How to Create a chart in PowerPoint using C#.Suppose i have the date in x axis and some arbitrary values in Y axis?
|
|
|
|
|
Google is your friend: Be nice and visit him often. He can answer questions a lot more quickly than posting them here...
A very quick search using your subject as the search term gave over half a million hits: How to Create a chart in PowerPoint using C# - Google Search[^]
In future, please try to do at least basic research yourself, and not waste your time or ours.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Hi everybody,
i have created a user control combined with textbox and label.
i created text and label register to modify the label and textbox.
when i tried to bind the text and label nothing is shown.
here's the xaml of the user control:
<UserControl x:Class="Gestione_WPF.LabelledTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Gestione_WPF"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="200">
<Grid Background="White" FlowDirection="RightToLeft">
<Label x:Name="lbl" Content="{Binding Label, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Background="{StaticResource gradientBrushTabControlHeader}">
<Label.Style>
<Style TargetType="Label">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<StackPanel Orientation="Horizontal">
<Border Background="{StaticResource ResourceKey=gradientBrushSegmentedTabItem}" Width="200" BorderThickness="0,0,0,0">
<StackPanel Orientation="Horizontal">
<Viewbox StretchDirection="DownOnly" Stretch="Uniform">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" TextBlock.FontSize="14" TextBlock.Foreground="#FFFFFF" Margin="5">
<ContentPresenter.Effect>
<DropShadowEffect BlurRadius="0.0"
Color="#032A6B"
Direction="90"
Opacity="1"
ShadowDepth="1" />
</ContentPresenter.Effect>
</ContentPresenter>
</Viewbox>
</StackPanel>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Label.Style>
</Label>
<TextBox x:Name="txt" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="120" HorizontalAlignment="Right">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border CornerRadius="0,0,0,50" BorderBrush="Black" Background="White" BorderThickness="0">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" TextBlock.FontSize="14" TextBlock.Foreground="#FFFFFF" Margin="5">
<ContentPresenter.Effect>
<DropShadowEffect BlurRadius="0.0"
Color="#032A6B"
Direction="90"
Opacity="1"
ShadowDepth="1" />
</ContentPresenter.Effect>
</ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
</UserControl>
here's the usercontrol.cs:
public partial class LabelledTextBox : UserControl
{
public LabelledTextBox()
{
InitializeComponent();
this.DataContext = this;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
}
public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(LabelledTextBox), new PropertyMetadata(null));
public string Label
{
get { return (string)this.GetValue(LabelProperty); }
set { this.SetValue(LabelProperty, value);}
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(LabelledTextBox), new PropertyMetadata(null));
public string Text
{
get { return (string)this.GetValue(TextProperty); }
set { this.SetValue(TextProperty, value); }
}
}
and here's the implmentation:
<controls:LabelledTextBox Label="{Binding Hello}" Text="{Binding World}"/>
Why the binding not showing? if the label i'm doing without binding it works, but the text don't and i can't write inside the textbox.
|
|
|
|
|
So; you're saying you have properties called "Hello" and "World" somewhere?
Did you implement the INotifyPropertyChanged interface?
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
I did implement INotifyPropertyChanged but i finally solved my problem
i remove this.DataContext = this; from the user control
and added relative reference
to label content:
Content="{Binding Label, RelativeSource={RelativeSource AncestorType=UserControl}}"
and textbox text:
Text="{Binding Text,RelativeSource={RelativeSource AncestorType=UserControl}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
|
|
|
|
Hi there. I have following scenario
- one machine with a service installed (machine 1)
- one remote machine with public ip (machine 2)
- one machine with web application (machine 3)
All these machines could be in the same premises or in different. Since all of these machines and their respective software could be installed in any order, I don't know how to get machine 2's IP. Because my service on machine 1 will use this IP to upload data to it. And, of course, web application on machine 3 will display this data.
Any idea what API/library could I use on machine 1 to recieve machine 2's IP? Thanks for anything you share.
|
|
|
|
|
The user will have to enter it; there's no way that any api or library could "guess" which computer is meant with "machine 2".
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Why don't you have machine 2 login to machine 1 and upload (i.e. FTP); instead of 1 calling 2, etc.
A scheduler on #2 and an event / file handler on #1 should suffice; based on your description.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
//Report Load page code using dataset
private void RPT_SupplierPer_Load(object sender, EventArgs e)
{
crystalReportViewer1.ReportSource = null;
DataTable dt = new DataTable();
SqlConnection con = new SqlConnection(cs.cstring());
con.Open();
SqlCommand cmd = new SqlCommand("RPT_Sup_All", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@id",ID);
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds = new System.Data.DataSet();
//SupplierPer sp = new SupplierPer();
//da.Fill(ds);
// ds.Tables[0].TableName="RPT_Sup_All";
SupplierPer sp = new SupplierPer();
sp.Database.Tables[0].SetDataSource(ds.Tables[0]);
sp.SetDataSource(ds);
crystalReportViewer1.ReportSource = sp;
crystalReportViewer1.Refresh();
}
//print button code
private void btnPrint_Click(object sender, EventArgs e)
{
int id = Convert.ToInt16(txt_id.Text);
RPT_SupplierPer pt = new RPT_SupplierPer(id);
pt.Show();
}
|
|
|
|
|
You have already posted this in Question section.
modified 20-Sep-20 21:01pm.
|
|
|
|
|
My project would not run probably since i have 2 js file are crashing, but these 2 js files are important in my project and cant throw it. how can i solve this by other ways. TQ
|
|
|
|
|
And you want to use C# to solve the problem?
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Downvote countered.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|