updating GUI status bar from DLL [closed] - c#

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have one application developed in C# and one C# dll which i am using for serial communication.
after every 10 seconds i want to update the GUI from dll and want to send status message from dll to the Main program.
callback maybe the option for this. but not able to write it correctly.
It will be great if someone can give me proper syntax.

So this is just an example. First, the code from your DLL which exposes an event.
class MyWorkerClass
{
public event EventHandler<System.ComponentModel.ProgressChangedEventArgs> Changed;
void OnChanged(ProgressChangedEventArgs args)
{
if (Changed != null) Changed(this, args);
}
public void DoWork(object state)
{
// do your work
OnChanged(new ProgressChangedEventArgs(50, state); // use percentage
}
}
And the code in your GUI.
public class MyGUI
{
readonly MyWorkerClass worker;
public MyGUI()
{
this.worker = new MyWorkerClass();
this.worker.Changed += OnWorkerChanged;
}
public void OnWorkerChanged(object sender, ProgressChangedEventArgs args)
{
// ToDo: use args.ProgressPercentage to update a GUI element (example: ProgressBar)
// Remark: make sure you are in the GUI thread. Use this.InvokeRequired to check
}
}

Use a delegate:
public class SerialReader
{
public Action<string> Callback;
public void Read()
{
if (Callback != null)
Callback("Here is a message for the status bar");
}
}
Which the GUI class registers for:
public class GuiClass
{
public void foo() {
var reader = new SerialReader();
reader.Callback = UpdateStatusBar;
}
public void UpdateStatusBar(string message) {
statusBar.Text = message;
}
}
Make sure the Callback is set somewhere in your GUI code:
reader.Callback = UpdateStatusBar;

Related

How can I prevent repetition of a code block ending in return? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have a block of code which is used multiple times in multiple class methods. I would like to make it into a separate function, but the code block in question is an if statement with a return, e.g.
private void method() {
//..
if (condition) {
//..
return;
}
//..
}
The problem is that if I pull this out into a separate function, the return applies only to that function itself, and no longer to the class methods in question. What is the best way to deal with this situation?
A good solution is to extract the condition code to a new method that returns a bool and handle this in every method. The code might look a little like this:
private bool CheckCondition()
{
if (!condition) // Please recognize the NOT for this condition.
{
return true;
}
// .. your code from if statement
return false;
}
private void Method()
{
if (!this.CheckCondition())
{
return;
}
// ...
}
For completeness - there is another way but I would not recommend that:
private void WithCondition(Action action)
{
if (condition)
{
// ..
return;
}
action();
}
private void Method()
{
void Body()
{
// your old method body code after your condition here
}
this.WithCondition(Body);
}
But that looks weird. There are use cases for local functions like factory methods e.g. for non-blocking or some event handlers. But your case is not a common use case for that.

Since we have multicast delegates, why do we need events? [duplicate]

This question already has answers here:
Difference between events and delegates and its respective applications [closed]
(10 answers)
Closed 3 years ago.
I was asked this question in an interview, and either I'm suffering from brain-lock or just plain dumb, but I didn't have an answer.
Couple of reasons why we need events:
Restricting scope, you do not want to expose your events, like you can for your delegates.
You can have events as fields in your interfaces and not delegates
Example below:
Class Printer
{
public event EventHandler Print;
public void Start()
{
OnPrint();
}
protected virtual void OnPrint()
{
Print?.Invoke(this,EventArgs.Empty);
}
}
class Program
{
static void Main(string[] args)
{
//When Print is an EventHander
var printer = new Printer();
printer.Print += PrintEvent;
printer.Start();
//If Print was a delegate this is possible, else you get compile time errors
printer.Print(null,null); // Events will not allow to have a direct invoke
printer.Print = null; //You cannot assign a null to an Event Handler
}
private static void PrintEvent(object sender, EventArgs e)
{
System.Console.WriteLine("Printing event");
}
}

C# update UI from different class/thread [duplicate]

This question already has answers here:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on
(22 answers)
Closed 5 years ago.
Good morning guys, I'm trying to write some application in C#, where I like to update the UI (A progress bar in this case) from another thread and class.
But I just can't get it to work, I googled and search around but I'm afraid I just don't get it. I have a windows form application, I start a thread when I click a button, and somewhere in this thread I would like to update my UI.
I either get:
An object reference is required for the non-static field, method, or property
or something in the direction of the object being created by a different thread.
(At the location where I try to call Form1.UpdateProgressBar(value); in fileReader).
I have no experience in object orienting programming, I usually stick with C. If anyone could tell me the right way to do this, I would be very happy.
Edit_1: Alright.. Combinations of errors, the answer so far might have helped if I didn't have he static issue. And fixing the static issue by making the entire class static creates another X amount of errors on its own, including:
Static classes cannot have instance constructors
namespace TestCode
{
public partial class Form1 : Form
{
static fileReader SourceReader;
public Thread SearchThread { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
folderBrowserDialog1.ShowDialog();
Console.WriteLine(folderBrowserDialog1.SelectedPath);
this.SearchThread = new Thread(new ThreadStart(this.ThreadProcSafe));
this.SearchThread.Start();
}
public void UpdateProgressBar( int value)
{
progressBar1.Value =value;
}
private void ThreadProcSafe()
{
SourceReader = new fileReader(folderBrowserDialog1.SelectedPath);
}
}
}
Class 2:
namespace TestCode
{
class fileReader
{
public fileReader(String path)
{
int value = 20;
/*Do some stuff*/
Form1.UpdateProgressBar(value);
}
}
}
Check if an invoke is required and inf needed then use the controls Invoke function:
public void UpdateProgressBar( int value)
{
if(progressBar1.InvokeRequired){
progressBar1.Invoke(new MethodInvoker(() => progressBar1.Value=value));
}else{
progressBar1.Value =value;
}
}
You can use a MethodInvoker when trying to modify the UI from another class like this:
ProgressBar progressBar = Form1.progressBar1;
MethodInvoker action = () => progressBar.Value = 80;
progressBar.BeginInvoke(action);
while you can use this when working in a different Thread ( a Task for example ):
progressBar1.Invoke((Action)(() => progressBar1.Value=50))
But consider the comments on your post. It's not needed to be dependent on Forms in fileReader
Side note: I don't know how you didn't find your problem on here:
how to update a windows form GUI from another class?
How to update the GUI from another thread in C#?

unity updating variable from different thread [duplicate]

This question already has answers here:
Use Unity API from another Thread or call a function in the main Thread
(5 answers)
Closed 6 years ago.
I am starting to learn some unity and I have a quick question in regards to multithreading.
I have a class which contains an instance of a datamodel class. The primary function of the class is the fetch a remote resource asynchronously and update the datamodel class. Then in the update function the datamodel class is read out and written to some text in a gameobject.
Anyway I am worrying that it could cause some issues related to multithreading since my async updating of the class could run at the same time as the update function causing a race condition. Do I have to wrap access to the class in a mutex?
class Data {
public int Number { get; set; }
public string Name { get; set; }
}
class Network : MonoBehaviour {
private Data d;
public void Start() {
// setting up handler to async fetch data and call provided callback
Networking.GetData(s => ParsePayload(s));
}
private void ParsePayload(string payload) {
d = JsonConvert.DeserializeObject<Data>(payload);
}
public void Update() {
var label = GameObject.Find("textObject").GetComponent<Text>();
label.Text = d.Name;
}
}
So am I right in this or does unity handle this by itself?
thx for any advice!
So am I right in this or does unity handle this by itself?
You are right in this. It could cause some problems and Unity does not handle this by itself. You are responsible to making sure that only one Thread can access d variable at a time. There are several ways of this but using the lock keyword can accompilsh this.
Since d is updated in the ParsePayload function and accessed in the Update function, you have to use the lock keyword in both functions.
Another unrelated problem is the GameObject.Find("textObject"). This should be done in the Start() function and saved to a variable. Don't do that in the Update function each frame.
class Network : MonoBehaviour
{
private Data d;
Text label;
private System.Object threadLocker = new System.Object();
public void Start()
{
label = GameObject.Find("textObject").GetComponent<Text>();
// setting up handler to async fetch data and call provided callback
Networking.GetData(s => ParsePayload(s));
}
private void ParsePayload(string payload)
{
lock (threadLocker)
{
d = JsonConvert.DeserializeObject<Data>(payload);
}
}
public void Update()
{
lock (threadLocker)
{
label.text = d.Name;
}
}
}

Help explain code with delegates

Im new to C# and the framework Im playing with and Im trying to figure out how some code works (there is nothing wrong with the code). Its a client/server application that sends some text from the client to the server and then receives and displays the same string in a textbox.
The code below is from the client and its form. Only the stuff for receiving the string from the server is included here. I included some comments from the framework.
public class TestModuleMobile : PreCom.Core.ModuleBase, PreCom.Core.IForm
{
public delegate void ReceiveDelegate(string data);
public event ReceiveDelegate DataReceived;
public void Receive(byte[] data)
{
string text = Encoding.UTF8.GetString(data, 0, data.Length);
if (DataReceived != null)
DataReceived.Invoke(text);
}
public override bool Initialize()
{
PreCom.Application.Instance.Communication.Register(99, Receive);
// Register(uint receiverID, RecieveDelegate receiver): Called by modules to register for communication.
//
// Parameters:
// receiverID:
// Module Id
// receiver:
// The module receive function that will be called by the framework when data
// arrives to specific module. (This method should return as soon as possible
// to avoid timeouts)
_isInitialized = true;
return true;
}
}
public partial class TestModuleMobileForm : PreCom.Controls.PreComForm
{
TestModuleMobile _module;
public TestModuleMobileForm(TestModuleMobile module)
{
_module = module;
_module.DataReceived += new TestModuleMobile.ReceiveDelegate(DataReceived);
InitializeComponent();
}
void DataReceived(string data)
{
if (InvokeRequired)
{
ThreadStart myMethod = delegate { DataReceived(data); };
this.BeginInvoke(myMethod);
return;
}
listBox1.Items.Insert(0, data);
this.preComInput21.Text = "";
}
}
Questions:
1. public override bool Initialize()
The function call to Register takes a ReceiveDelegate object as a second parameter. So how can I send a function to it (Receive) when its just a function? How does this work?
2. public void Receive(byte[] data)
What happens in the if-case? How does invoke work?
3. void DataReceived(string data)
What happens in the if-case (line by line)?
There are many related posts here on Stackoverflow which you can browse through to get a better understanding of delegates. Once you have read through them, take a relook at your code and you will find it easier to understand.
Tip: Check to the right side of this web page to see all the related posts.
You need a full understading of delegates so you better start by reading these in order:
Delegates (C# Programming Guide)
Delegates Tutorial
Delegates and Events in C# / .NET

Categories