I can't quite come up with the solution to creating a generic method to handle the InvokeRequired for void methods (I'll deal with return values later). I was thinking something like:
// Probably not the best name, any ideas? :)
public static void CheckInvoke(this Control instance,
,Action<object, object> action)
{
if (instance.InvokeRequired)
{
instance.Invoke(new MethodInvoker(() => action));
}
else
{
action()
}
}
Then I could write something like:
public partial class MyForm : Form
{
private ThreadedClass c = new ThreadedClass();
public MyForm()
{
c.ThreadedEvent += this.CheckInvoke(this
,this.MethodRequiresInvoke
,sender
,e);
}
}
This doesn't compile obviously, I just can't quite tie it together.
Hans is correct, in that you probably don't want to wrap code like this up, especially since it can cause some debugging issues down the road in determining what thread actions are happening on. That said, this would be the signature you'd want:
public static class FormsExt
{
public static void UnwiseInvoke(this Control instance, Action toDo)
{
if(instance.InvokeRequired)
{
instance.Invoke(toDo);
}
else
{
toDo();
}
}
}
Loose Action parameters of "object,object" (as JerKimball suggests), name it SafeInvoke, and attach to event via anonymous delegate:
c.ThreadedEvent += delegate
{
c.SafeInvoke(this.MethodRequiresInvoke);
};
Related
Is there a way I could use reflection to hook one function to another without using delegates?
class A
{
void Foo()
{
}
}
class B
{
void Main()
{
A a = new A();
a.GetType().GetMethod("Foo").AddHook(a, Func); //I want something like this
a.Foo();
//Func gets called
}
void Func()
{
}
}
Is there a way to call Func after Foo was called without using events, delegates or just calling Func from inside Foo?
I need this so my game's UI controller can get updated.
The way I see most people dealing with this is by adding a bunch of events to A and subscribing B to those. Like this
class A
{
public delegate void UICallback();
public event UICallback onFoo;
void Foo()
{
onFoo.Invoke();
}
}
class B
{
void Main()
{
A a = new A();
a.onFoo += Func;
a.Foo();
}
void Func()
{
}
}
The problem I find with this approach is that I'd need to add a bunch of events like these (probably more than 5 or even 10) to many classes and then remember to invoke those at the end of a function to update UI (invoke onBattleStarted at the end of StartBattle(), for example). This, in addition to increasing the size of my classes with big blocks of event declarations making it ugly to read, makes it a harder maintain.
EDIT I think no one really understands what I'm looking for... I'd like a way to hook Func to Foo without making any changes to Foo, i.e. without Foo knowing this callback exists. Using an action won't help since I'd need specify on Foo's parameters that it should call Func
Thank you for your help!
You Can call Action at the end of Func().
Class A
{
void Foo()
{
}
}
Class B
{
void Main()
{
A a = new A();
Func( () => {a.Foo();});
}
void Func(Action onFinish)
{
//Enter your code here
onFinish();
}
There is the method chaining pattern if that can solve your problem:
namespace Assets
{
public class Example
{
public Example GrabSomeFoodInTheFridge()
{
// some work
return this;
}
public Example WatchTv()
{
// some work
return this;
}
public Example EatFood()
{
// some work
return this;
}
}
public class Demo
{
public Demo()
{
var example = new Example();
var instance = example
.GrabSomeFoodInTheFridge()
.EatFood()
.WatchTv();
}
}
}
It does not use reflection at all, additionally you could leverage interfaces and extension methods.
I would like to create a pattern like the following:
namespace SharedUtilities
{
public partial class PartialClass
{
public void DoSomethingInteresting()
{
DoSomethingPlatformSpecific();
}
partial void DoSomethingPlatformSpecific();
}
}
But I would like to add a callback argument so that I can pass in a different callback depending on the platform. Can anyone point me in the right direction here? I have been reading up on Action, EventHandler<>, and delegate, but I'm not sure which one to use in this scenario. Any advice would be appreciated.
There are a lot of ways to do that and handle this kind of scenario, the simplest one would be like this -
namespace SharedUtilities
{
public partial class PartialClass
{
public void DoSomethingInteresting(Action<Type1, Type2> action)
{
//code logic
action(p1, p2);
}
}
}
Then use it like this -
With lambda
(new SharedUtilities.PartialClass()).DoSomethingInteresting((param1, param2)=>
{
//codes
});
Without Lambda
public void DoSomethingInterestingSpecific(Type1 param1, Type2 param2)
{
//code logic
}
(new SharedUtilities.PartialClass()).DoSomethingInteresting(DoSomethingInterestingSpecific);
That is one way of doing this, there are other ways too, like abstract factory pattern, event delegate callback, etc.
Func<...> has a return value, Action<...> does not. Callbacks should usually be Action<...>
If you want to structure the code such that classes other than the one calling the function can be notified when it's complete, define an event.
I'm experimenting a lot with Reactive Extensions and right now I'm trying to make a system in which I can queue procedures and execute them in whatever fashion I want while being able to send notifications to subscribers.
I currently have my database access encapsulated within a UserAccess class that exposes the method to add a user. In that method I would like to queue an action that adds a user to the database. So I made a JobProcessor of T class that exposes a method QueueJob(Action) and have my User implement this class. My problem is I can't see how to call the Action from within the OnNext method of the Observable because the action takes a User parameter.
My angle of attack must be wrong and there must be a problem with my grasp of the design. For example I know I should somehow pass my user to the QueueJob procedure but I don't know how to do it in a clean way.
public class UserAccess : JobProcessor<User>
{
public void AddUser(User user)
{
QueueJob(usr =>
{
using (var db = new CenterPlaceModelContainer())
{
db.Users.Add(usr);
}
});
[...]
public abstract class JobProcessor<T>
{
// Either Subject<T> or Subject<Action<T>>
private Subject<Action<T>> JobSubject = new Subject<Action<T>>();
public JobProcessor()
{
JobSubject
/* Insert Rx Operators Here */
.Subscribe(OnJobNext, OnJobError, OnJobComplete);
}
private void OnJobNext(Action<T> action)
{
// ???
}
private void OnJobError(Exception exception)
{
}
private void OnJobComplete()
{
}
public void QueueJob(Action<T> action)
{
JobSubject.OnNext(action);
}
}
Edit 1 :
I tried to change the signature of QueueJob to
QueueJob(T entity, Action<T> action)
Now I can do
QueueJob(user, usr => { ... } );
But it does not seem very intuitive. I haven't seen many frameworks in which you pass both the entity and the action. With that I might as well not need the JobProcessor.
Edit 2 :
I changed my JobProcessor's subject type to Subject, removing the T altogether. Since there was no need to include the User in the procedure since I can refer to it externally. The only problem now is if the User I pass to the QueueJob's action changes between the actual time of the Action execution, the user will have the modified information. Undesirable but I guess I will continue looking for a solution.
My code is now (used Buffer for sample) :
public abstract class JobProcessor
{
public Subject<Action> JobSubject = new Subject<Action>();
public JobProcessor()
{
JobSubject
.Buffer(3)
.Subscribe(OnJobNext, OnJobError, OnJobComplete);
}
private void OnJobNext(IList<Action> actionsList)
{
foreach (var element in actionsList)
{
element();
}
}
private void OnJobError(Exception exception)
{
}
private void OnJobComplete()
{
}
public void QueueJob(Action action)
{
JobSubject.OnNext(action);
}
}
First off, I have to agree with Lee and NSGaga that you probably don't want to do it this way - there are other patterns for a Producer/Consumer queue that are far more aligned with what (I think) you are trying to accomplish here.
That said, since I can never resist a challenge...with some minor tweaks, you can remove your immediate problem of "What do I pass into the action?" by just capturing the user parameter passed in and making it a straight-up Action - Here's your code with some modifications:
public class UserAccess : JobProcessor
{
public void AddUser(User user)
{
QueueJob(() =>
{
using (var db = new CenterPlaceModelContainer())
{
db.Users.Add(user);
}
});
[...]
public abstract class JobProcessor
{
// Subject<Action>
private Subject<Action> JobSubject = new Subject<Action>();
public JobProcessor()
{
JobSubject
/* Insert Rx Operators Here */
.Subscribe(OnJobNext, OnJobError, OnJobComplete);
}
private void OnJobNext(Action action)
{
// Log something saying "Yo, I'm executing an action" here?
action();
}
private void OnJobError(Exception exception)
{
// Log something saying "Yo, something broke" here?
}
private void OnJobComplete()
{
// Log something saying "Yo, we shut down" here?
}
public void QueueJob(Action action)
{
JobSubject.OnNext(action);
}
}
I'm not frankly sure what is your `goal' here - but I think you got it backwards a bit...
Normally subject is exposed via property like
IObservable<Action<T>> NewJob {get{return _subject;}}
...or something. (Subject becomes observable - subject is dual in nature - and why it's specific - and a bit controversial - but good for playing around etc.)
And you just call OnNext from inside the class - like you did.
But you do not normally subscribe to the observable yourself
...you let the outside users do that by 'hooking' into your property - and defining subscribe - which gets them new items as they arrive.
This is simplified of course, there are many cases and many uses but this might help I hope
My initial reaction is that IObservable is normally best suited for creating sequences of immutable data structures, not method-pointers/delegates/actions.
Next I would suggest that if you are trying to 'schedule' actions to be processed in a queue fashion, then the IScheduler implementations in Rx seem like a perfect fit!
Alternatively if you are actually trying to create a ProduceConsumer Queue, then I dont think Rx is actually the best fit for this. i.e. if you are putting a heap of messages into a queue and then having some consumers reading these messages off and processing them, I would look to a different framework.
I finalized my design and found something that I like. Here is the code if anyone else needs it.
public class JobProcessor<T> : IDisposable where T : new()
{
private ISubject<Action<T>> jobsProcessor = new Subject<Action<T>>();
private IDisposable disposer;
private T _jobProvider = new T();
public JobProcessor(Func<ISubject<Action<T>>, IObservable<IEnumerable<Action<T>>>> initializer)
{
Console.WriteLine("Entering JobProcessor Constructor");
disposer = initializer(jobsProcessor)
.Subscribe(OnJobsNext, OnJobsError, OnJobsComplete);
Console.WriteLine("Leaving JobProcessor Constructor");
}
private void OnJobsNext(IEnumerable<Action<T>> actions)
{
Debug.WriteLine("Entering OnJobsNext");
foreach (var action in actions)
{
action(_jobProvider);
}
Debug.WriteLine("Leaving OnJobsNext");
}
private void OnJobsError(Exception ex)
{
Debug.WriteLine("Entering OnJobsError");
Debug.WriteLine(ex.Message);
Debug.WriteLine("Leaving OnJobsError");
}
private void OnJobsComplete()
{
Debug.WriteLine("Entering OnJobsComplete");
Debug.WriteLine("Leaving OnJobsComplete");
}
public void QueueJob(Action<T> action)
{
Debug.WriteLine("Entering QueueJobs");
jobsProcessor.OnNext(action);
Debug.WriteLine("Leaving QueueJobs");
}
public void Dispose()
{
disposer.Dispose();
}
}
I selected a generic make to support an architecture in layers where I could use the JobProcessor in a layer of concurrency where I could select how fast or slow my execution can be. The JobProcessor constructor takes a Func used to declare the Observable sequence somewhere else in the code and generate a processor that executes jobs an the order described by the sequence. The OnNext takes in an IEnumerable> to be able to support sequences like .Buffer(3) that returns a batch of actions at the same time. The downside to that is that when creating a sequence returning single actions at a time I need to do this
var x = new JobProcessor<DatabaseAccess<User>>(subject => subject.Select(action => action.Yield()));
The Yield() extension methof of T returns an enumerable of a single element. I found it here Passing a single item as IEnumerable<T>.
I am trying to use a method inside class, from another class.
namespace Crystal.Utilities
{
public class Logging
{
public static void Log()
{
//dostuff
Crystal.MainForm.general_log_add_item("Hello World");
}
}
}
namespace Crystal
{
public partial class MainForm : Form
{
public void general_log_add_item(string msg)
{
listBox1.Items.Add(msg);
}
}
}
I want to be able to call Crystal.Utilities.Logging.Log() from anywhere, and that to be able to call Crystal.MainForm.general_log_add_item() . But It doesn't let me, because if I put it as public, then I can't see it, if it's static then It can't interact with my listbox.
This is a wrong approach. Your class should not call into the UI, as the UI could change. The class should not know nor care about the UI. Instead, the class could expose an event that the form could subscribe to, and update based upon the information contained within the event's arguments.
Here's a hastily thrown together example.
class Program
{
static void Main()
{
Logger.OnLogging += Logger_OnLogging;
Logger.Log();
Logger.OnLogging -= Logger_OnLogging;
}
static void Logger_OnLogging(LoggingEventArgs e)
{
Trace.WriteLine(e.Message);
}
}
public class Logger
{
public delegate void LoggingEventHandler(LoggingEventArgs e);
public static event LoggingEventHandler OnLogging;
public static void Log()
{
// do stuff
RaiseLoggingEvent("Data logged");
}
protected static void RaiseLoggingEvent(string message)
{
if (OnLogging != null)
OnLogging(new LoggingEventArgs(message));
}
}
public class LoggingEventArgs : EventArgs
{
public LoggingEventArgs(string message)
{
this.Message = message;
}
public string Message { get; private set; }
}
Instead of implementing it as a static method, try implementing as a singleton. It's a common trick to make an instance global in scope, and restrict to one instance, without making everything static (and thus unable to be used as an instance).
You have to understand that the window is not static, there is one instance of him, thats why the method cant be static,
you can use
Application.Windows to reach this instance and call the add method.
or you can register the window in his constructor on another class that will mediate the Logging and the window.
If you don't understand tell me and I'll try to be more clear
When you declare a method as "static" you're saying that it's not dependent upon a specific instance of the class it's in.
For example if you have a class named "chair" and you want to count how many chairs there are, you'll do that with a static field, and a static method to return that field's value.
The count of all chairs is not related to a specific chair.
In your case you want to add a static method to add an item to a specific instance of a Form. That's impossible and doesn't make sense.
If you want to add an item to a listBox, it must be through a public method.
So basically what I'm saying is - rethink what you're trying to do, there's a good explanation as to why you're not succeeding in doing that.
I have gotten a bit lazy(it's sometimes good) and started updating WinForms UI by invoking a callback without checking InvokeRequired first.
Are there a performance issues or considerations that I should be aware of?
private delegate void SetStatusEventHandler(string statusMessage);
private void SetStatus(string statusMessage)
{
Invoke((MethodInvoker) (() =>
{
resultLabel.Text = statusMessage;
}));
// - vs -
if (InvokeRequired)
{
SetStatusEventHandler cb = SetStatus;
Invoke(cb, statusMessage);
}
else
{
resultLabel.Text = statusMessage;
}
}
[EDIT]: Most of times that a method that calls "invoke" will be called at most like say 10~20 times a second with a wide interval inbetween.
[UPDATE] Settled with the following extension method
public static class SmartInvoker
{
public static void InvokeHandler(this Control control, MethodInvoker del)
{
if (control.InvokeRequired)
{
control.Invoke(del);
return;
}
del();
}
}
...
private void SetStatus(string statusMessage)
{
this.InvokeHandler(() => resultLabel.Text = statusMessage);
}
I guess finding out how to manage extension method classes is another topic I need to dig in. Thank you for your help
EDIT: See the comments for debate about the whole posting vs immediately dispatching malarky.
Either way, my answer is actually the same: unless this is happening hugely often unnecessarily (i.e. most of the time you're on the UI thread to start with, and it's attached to something like a mouse movement handler) I wouldn't worry. It certainly makes the code simpler. If this is going to be invoked very often, I'd measure and test more :)
Invoke is faster with an EventHandler or MethodInvoker delegate than with others. I don't know if there's any difference between the two - you may want to check.
You can make this even simpler by writing an extension method, e.g.
public static void InvokeHandler(this Control control, MethodInvoker handler)
{
control.Invoke(handler);
}
Then you can make your code:
private void SetStatus(string statusMessage)
{
this.InvokeHandler(delegate
{
resultLabel.Text = statusMessage;
});
}
or
private void SetStatus(string statusMessage)
{
InvokeHandler(() => resultLabel.Text = statusMessage);
}
That way you don't need to specify the delegate type.
Why not just add an extension method so you don't have to think about it anymore?
public static object SmartInvoke(this Control control, MethodInvoker del) {
if ( control.InvokeRequired ) {
control.Invoke(del);
return;
}
del();
}
Now your code becomes
private void SetStatus(string statusMessage) {
this.SmartInvoke(() => resultLabel.Text = statusMessage);
}
I believe it just prevents an unnecessary post if you're already on the same thread. So if that would be the most common scenario (being on the correct thread), it might cause a small performance hit by not checking, but I dont believe its actually required.