I am currently using JADE to build an agent-based platform to solve scheduling problems. The case is that, a defined behaviour extends AchieveREInitiator doesn't work properly in some specific state of the programme.
This is the behaviour class:
class ACOInitiator extends AchieveREInitiator {
Agent myAgent;
List<Schedule> roundSchedules;
public ACOInitiator(Agent a, ACLMessage msg) {
super(a, msg);
this.myAgent = a;
roundSchedules = new ArrayList<Schedule>();
System.out.println(msg.getContent()); //This is properly printed.
// TODO Auto-generated constructor stub
}
#Override
protected Vector prepareRequests(ACLMessage request) {
System.out.println(request.getContent()); //In some specific state, this is not printed.
Vector v = new Vector(1);
for (int i = 1; i <= Properties.antNum; i++) {
AID aAID = new AID("Ant" + i, AID.ISLOCALNAME);
request.addReceiver(aAID);
aAID = null;
}
v.addElement(request);
return v;
}
#Override
protected void handleAgree(ACLMessage agree) {
try {
roundSchedules.add((Schedule) (agree.getContentObject()));
} catch (UnreadableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
agree = null;
}
#Override
protected void handleAllResponses(Vector responses) {
Collections.sort(roundSchedules);
Environment.iterSolution = roundSchedules.get(0);
roundSchedules = null;
Environment.setState(Environment.STATE_ITERATION_CHECKING);
responses = null;
myAgent.removeBehaviour(this);
}
}
When the programme is executed, the following results are shown:
Generate solution.
Generate solution.
Iteration #1: 788.0(0.48s) (New best solution)
Generate solution.
Generate solution.
Iteration #2: 809.0(0.12s) r = 1/2
Generate solution.
Generate solution.
Iteration #3: 793.0(0.08s) r = 2/2
......
----- Simulation starts -----
......
#120
Breakdown machines:
Repaired machines:
Incoming jobs: 2-5;
Generate solution.
----- All schemes finished -----
This is unwanted. Apparently, the two Strings to be printed is the same. That's why every iteration in the solution stage, 2 "Generate solution." are printed. However, in the later simulation stage, only 1 "Generate solution." is printed and the programmes goes to the end. It can be inferred that the "prepareRequests" method in not auto called, as in earlier stage.
I'm new to JADE and the problem has bothered me a couple of days. Please help if you are a JADE programmer.
I'm not sure I understand your question or problem but from what I can see the first printout "Generate solution" happens in the constructor:
public ACOInitiator(Agent a, ACLMessage msg) { -> System.out.println(msg.getContent())
the second one in the prepare requests method:
protected Vector prepareRequests(ACLMessage request) {-> System.out.println(msg.getContent())
.
Also remember when interacting with multiple agents the initiator behaviour will wait for a response from all its responder behaviours.
Hope this helps, if it does not, try attaching sniffer diagrams.
Related
When I bind a "back button" to a the router in ReactiveUI, my ViewModel is no longer garbage collected (my view too). Is this a bug, or is this me doing something dumb?
Here is my MeetingPageViewModel:
public class MeetingPageViewModel : ReactiveObject, IRoutableViewModel
{
public MeetingPageViewModel(IScreen hs, IMeetingRef mRef)
{
HostScreen = hs;
}
public IScreen HostScreen { get; private set; }
public string UrlPathSegment
{
get { return "/meeting"; }
}
}
Here is my MeetingPage.xaml.cs file:
public sealed partial class MeetingPage : Page, IViewFor<MeetingPageViewModel>
{
public MeetingPage()
{
this.InitializeComponent();
// ** Comment this out and both the View and VM will get garbage collected.
this.BindCommand(ViewModel, x => x.HostScreen.Router.NavigateBack, y => y.backButton);
// Test that goes back right away to make sure the Execute
// wasn't what was causing the problem.
this.Loaded += (s, a) => ViewModel.HostScreen.Router.NavigateBack.Execute(null);
}
public MeetingPageViewModel ViewModel
{
get { return (MeetingPageViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(MeetingPageViewModel), typeof(MeetingPage), new PropertyMetadata(null));
object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (MeetingPageViewModel)value; }
}
}
I then run, and to see what is up, I use VS 2013 Pro, and turn on the memory analyzer. I also (as a test) put in forced GC collection of all generations and a wait for finalizers. When that line is uncommented above, when all is done, there are three instances of MeetingPage and MeetingPageViewModel. If I remove the BindCommand line, there are no instances.
I was under the impression that these would go away on their own. Is the problem the HostScreen object or the Router that refers to an object that lives longer than this VM? And that pins things down?
If so, what is the recommended away of hooking up the back button? Using Splat and DI? Many thanks!
Following up on the idea I had at the end, I can solve this in the following way. In my App.xaml.cs, I make sure to declare the RoutingState to the dependency injector:
var r = new RoutingState();
Locator.CurrentMutable.RegisterConstant(r, typeof(RoutingState));
then, in the ctor of each view (the .xaml.cs code) with a back button for my Windows Store app, I no longer use the code above, but replace it with:
var router = Locator.Current.GetService<RoutingState>();
backButton.Click += (s, args) => router.NavigateBack.Execute(null);
After doing that I can visit the page as many times as I want and never do I see the instances remaining in the analyzer.
I'll wait to mark this as an answer to give real experts some time to suggest another (better?) approach.
I have method
public override void InitializeRow(object sender, InitializeRowEventArgs e)
{
if (!e.ReInitialize)
Task.Factory.StartNew(() =>
{
AfterInitializeRow(sender, e);
});
}
public override void AfterInitializeRow(object sender, InitializeRowEventArgs e)
{
foreach (UltraGridColumn ugc in e.Row.Band.Columns)
{
if (IsNumeric(ugc.Key))
{
e.Row.Cells[ugc].DroppedDown = true;
e.Row.Cells[ugc].ValueList = “Some value”;
e.Row.Cells[ugc].SetValue(e.Row.Cells[ugc.Key].Value, false);
e.Row.Cells[ugc].Style = Infragistics.Win.UltraWinGrid.ColumnStyle.DropDownList;
}
}
}
But its Giving error at e.Row.Cells[ugc].DroppedDown = true;
I learned that only Main thread can update the UI.
But is it possible that while updating the DroppedDown only it switch to main thread. Bcoz more than 1000’s rows are initialized in this way making the load of Grid very slow. So I want to do some kind of parallelism in this process.
In any function in your Form or UserControl, you can use the following type of code:
public void SetText(string text)
{
if (InvokeRequired)
{
BeginInvoke(new Action<string>(SetText), text);
}
else
{
label1.Text = text;
}
}
label1 would be the control to update in this case.
This will make sure that you invoke the function on the UI-thread.
You should still be careful with syncrhonization, though, but simply updating your UI from another thread can be easily done like that.
The answer to this question is that you shouldn't be using threading in the InitialzieRow event to set or even access properties on the grid or its related objects.
What you should do instead is look for ways to optimize what you are doing in this method first. For example why are you setting the value of a cell to the value it already has, this line of code should be able to be removed without impacting behavior.
Also all of the logic provided is only based on the column key so if the column has a consistent set of values, you could set the ValueList on the column in InitializeLayout instead of using InitializeRow.
I spend a lot of time working with Windows Forms controls but from a background worker thread - I suppose this is good practice really since you don't want your form to be locking up when people click buttons. To be honest, with just about everything GUI related action I normally do in a background worker thread, so the interface is nice an responsive to the user (Wish more people would do that!).
So my question is... every time I have to interact with controls I have to "Invoke" them, with something like:
if (control.InvokeRequired)
{
//
}
Standard practice right? However, this leads me to some terribly messy code, because just about every control type I have, I need a MethodInvoker delegate or something. It's adding thousands of lines of code to my protects, and its terribly time consuming.
I currently have hundreds of "property setting" methods like:
private void Safe_SetLableText(Label control, string text)
{
if (control.InvokeRequired)
{
control.Invoke((MethodInvoker)delegate
{
control.Text = text;
});
}
else
{
control.Text = text;
}
}
So, is there some other technique, or way to do this, or some way to being able to always alter a property of a control, no matter what the control is and no matter what thread im in?
something like: (pseudocode)
BackgroundWorker.RunWorkerAsync();
private void thing_to_do()
{
// We are in a background thread now
DoSomeDatabaseWorkThatTakesALongTime();
InvokeAnyControls();
// Do some stuff...
controlX.Text = "123"
controlY.Height = 300;
controlZ.text = ControlA.text;
RestoreAnyControls();
}
You could wrap your InvokeRequired code with a delegate, like so:
public static void Invoke2<TControl>(this TControl c, Action<TControl> code) where TControl : Control {
if( c.InvokeRequired ) c.Invoke( delegate() { code(c); } );
else code(c);
}
Then use it like so:
private void Safe_SetLableText(Label control, string text) {
control.Invoke2( c => c.Text = text );
}
Of course you might want better names than Invoke2, but I hope the idea sits will with you. Note that the lambda-expression syntax is a C# 3.0 feature, but the Action<T> delegate is part of .NET 2.0, so this will compile against the .NET Framework 2.0 so long as you're VS2008 or later.
I'm posting an answer to my own question because I think it will add value to the community.
1) I wanted to "simplify" my code, and one if the most important finds was that that the:
control.InvokeRequired
really isnt needed... its pretty much a given. Importantly, you CAN rely on the fact that the control will need to be invoked if you are in a background (or non-UI) thread.
2) The invocation travels "UP" the control tree, so if you have:
Form > Control > Control inside Control > etc > etc
You only need to invoke "Form" (top most), and then you can alter the properties of the child elements.
So here is my clean and simple solution to working with background workers (or non-UI threads). I have just tested this now and it works great.
public partial class Form1: Form
{
public Form1()
{
BackgroundWorker bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(this.bgDoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.bgComplete);
bgw.RunWorkerAsync();
}
private void bgComplete(object sender, EventArgs e)
{
// You are not in the UI thread now, so you can Invoke without error
this.Invoke((MethodInvoker)delegate
{
// Now you can change any property an any control within this form.
// Remember "this" refers to Form1.
this.label1.Text = "test123";
this.label2.Text = "test456";
this.label3.Text = this.label4.Text;
// You can set progress bars too, not just label text
}
}
private void bgDoWork(object sender, DoWorkEventArgs e)
{
// Do something that takes a long time
}
}
As you are already using the Background worker why don't you 'misuse' OnProgressChanged?
private void thing_to_do()
{
// We are in a background thread now
DoSomeDatabaseWorkThatTakesALongTime();
BackgroundWorker.ReportProgress(1, "state");
DoSomeMoreDatabaseWorkThatTakesALongTime();
BackgroundWorker.ReportProgress(2, YourObjectHere);
}
void OnProgressChanged(ProgressChangedEventArgs progressArgs)
{
switch(progressArgs.ProgressPercentage)
{
case 1:
// Do some stuff...
controlX.Text = "123"
controlY.Height = 300;
controlZ.text = ControlA.text;
break;
case 2:
// other stuff
YourObject obj = (YourObject) progressArgs.UserState;
// wahtever...
break;
default:
break;
}
}
I am looking for a way to display images on my ListField from a background thread. First in my drawListRow i try this
path = (String) imagePaths.elementAt(index);
bit = connectServerForImage(path);
g.drawBitmap(xText, y + yText, 80, 200, bit, 0, 0);
but can't scroll smoothly throughout the list, and they say do not do networking or other blocking operations on the UI. But i also try this
private class imgConnection extends Thread
{
public imgConnection() {
super();
}
public void run() {
try {
for (int i = 0; i < imagePaths.size(); i++)
{
final int index = i;
String path = imagePaths.elementAt(index).toString();
bit = connectServerForImage(path);
image.addElement(bit);
}
}
catch (Exception e)
{
System.out.println(e.toString());
}
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_list.setSize(image.size());
subManager.add(_list);
screen.invalidate();
}
});
}
}
public void drawListRow(ListField list, Graphics g, int index, int y, int w) {
bit = (Bitmap) image.elementAt(index);
g.drawBitmap(xText, y + yText, 80, 200, bit, 0, 0);
}
but nothing happens. Any idea, comments.
You are right, i just started java development 2 weeks ago particularly BB development and i try this link. I want to add a background thread to download image after i got the path url from json return.
first thread:
_connectionthread = new Connection();
_connectionthread.start();
private class Connection extends Thread
{
public Connection()
{
super();
}
public void run() {
try {}
catch (Exception e) {}
}
}
second thread:
_imgConnectionThread = new ImgConnection();
_imgConnectionThread.start();
private class ImgConnection extends Thread
{
public ImgConnection() {
super();
}
public void run() {
try {
}
catch (Exception e)
{
}
}
}
how to update images on ListField?
Answer is based on code from - pastebin.com/90UKTHzP
Terrible code! It's really hard to read and undersand! It looks like you copy pasted several examples from different locations. Also you overriding default behavior with same behavior. Also MainScreen already has VerticalManagerField. Also you're adding list every iteration to manager which will cause IAE. And main one thread is depended on result of second one. They start at the same time, but getting json from server and it's processing could take longer time, so image thread most probably will finish his run without any result.
So main recommendation to fix it - read clean code book! Read more about java development - conventions, multithreading. Read about BB development - UI api, networking.
And finally - start only one thread to get and parse json. After you get it finished - start another thread to get images.
There some minor things that could save you more battery and processor time also - start loading images on demand - when it painted or going to be painted (user scrolls list).
By convention, Java class names start with a capital letter, so imgConnection should really be ImgConnection.
In your sample code, I don't see imgConnection being instantiated anywhere, and I don't see any call to Thread.start(), which is the way a thread i started. Without Thread.start() it is not surprising nothing is happening - the thread is never starting.
Hi I play with GWT in the weekends, and I really like what i've seen
so far. I have 2 questions:
I don't really understand the execution model of my app. I think
that's because I don't know javascript. I'm assuming that there is
only one logical thread from the browser running the javascript and it
is the same thread that updates the display (disregarding asynchronous
requests). So when through js I add 50 elements to a frame, the 50
elements are displayed after all of them are added to the frame. In
other words, after the js has finished executing. Do I have it
right? Are there articles out there on this topic?
Sorry this is not a great example, but it may get my question
across. What do I do in the following situation (design):
a) update the text in a label to "starting..."
b) do a bunch of js and dom manipulation
c) update the text in the label to "finished!"
Currently, all I see is the after-effect: my dom manipulation and
"finished". The label never displays "starting..."
How can I force the label to refresh between step a & b. I've seen
some posts describing that one could use the Timer and somehow force
the element to refresh. But I can't figure out how this is achieved.
Looking forward to your suggestions. Thanks in advance.
To 1): Yes, javascript is single threaded. It is up to you to implement long running operations as non-blocking. Otherwise you're likely to run into Slow Script Warnings (see next point).
To 2): Have a look at the IncrementalCommand class (it's usage is described here). With it you can divide long running operations into chunks of smaller work and display progress updates to the user. A small example:
public class Starter implements EntryPoint {
private Label text = new Label();
private Label update = new Label();
#Override
public void onModuleLoad() {
Button btn = new Button("hit me");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
text.setText("starting...");
startIncrementalWork();
}
});
RootPanel.get().add(text);
RootPanel.get().add(update);
RootPanel.get().add(btn);
}
private void startIncrementalWork() {
IncrementalCommand cmd = new IncrementalCommand() {
private int count = 0;
#Override
public boolean execute() {
if (count >= 10000) {
text.setText("finished");
return false;
}
for (int i = 0; i < 100; i++) {
update.setText("count " + count);
count++;
}
return true;
}
};
DeferredCommand.addCommand(cmd);
}
}
Hope that helps.