Migrating the code from Bot Framework V3 to V4 - dialog

I have more question while migrating the dialog from V3 to V4. below is our code.
In v3, we were using
Microsoft.Bot.Builder.Dialogs.Conversation.SendAsync(conversationContext.CurrentActivity, new RootDialog());
public class RootDialog : IDialog {
public RootDialog()
{
.....
}
public async Task StartAsync(IDialogContext context)
{
context.Wait(this.MessageReceivedAsync);
}
public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
}
In the MessageReceivedAsync, we used the context.Wait(), context.Done() and context.PostAsync().
Can you recommend how to replace in the V4? And what's the alertnative for Microsoft.Bot.Builder.Dialogs.Conversation.SendAsync in V4?

These APIs are all gone. Here are the explanations of their replacements in V4:
context.Wait(…)
This method was used to tell the dialog system what method to invoke next on your class when a new activity arrived and is now gone. Instead you now subclass Dialog and override several methods for various lifecycle events:
BeginDialogAsync - called when the dialog is first pushed on the stack by bot code or another dialog calling BeginDialogAsync on the DialogContext.
ContinueDialogAsync - called when a new activity comes in and the bot calls ContinueDialog on the DialogContext.
ResumeDialogAsync - called when another dialog on the stack has completed and a dialog that was previously on the stack is now at the top of the stack.
RepromptDialogAsync - called when an explicit request has been made to reprompt the user. This is basically a way to tell the dialog that nothing has changed, but that it should pick up from where it left off again by sending whatever activity it last sent.
EndDialogAsync - called when the dialog has indicated its done and is being popped off the stack.
context.Done()/.Fail()
This was one of the way you reported the status of your dialog, but this is now accomplished by returning a DialogTurnResult from most of the aforementioned lifecycle methods. One of the properties is named Status and is of type DialogTurnStatus which has values that indicate the current state of the dialog. For example:
Waiting - the dialog sent some activities and is awaiting more input and should remain at the top of the stack.
Complete - the dialog has completed it's work and should be ended and popped off the stack. When this state is returned, callers can also investigate the output of the dialog (if it has one) which is passed back via the DialogTurnResult::Result property.
Cancelled - the dialog was cancelled part of the way through its work.
context.PostAsync()/Conversation.SendAsync
These were both used to respond back to the user. Both are now replaced by calling SendActivityAsync on the ITurnContext that is accessible via the Context property of the DialogContext instance that is passed into most of the aforementioned lifecycle methods as a parameter. NOTE: a couple of the lifecycle methods actually receive an ITurnContext parameter directly and then you just use that.

Related

How to schedule a task in Shopware 6

I have created a custom scheduled task. I have registered it as well using the following tutorial:
https://developer.shopware.com/docs/guides/plugins/plugins/plugin-fundamentals/add-scheduled-task#overview
However, in my database, the status of this task is still "queued" instead of "scheduled". This stops the task from executing. How to fix this? I am currently working on localhost.
Status queued means that a message to execute that task was dispatched to the message queue. If the status does not change automatically that indicates that now worker executed the messages from the queue.
By default (for dev setups!) there is a AdminWorker, which will poll and execute messages from the queue as long as the shopware administration is open in a browser. You can also start a worker manually per CLI:
bin/console messenger:consume
You can find more information how to work with the message queue and how to start workers in the official docs.
I had exactly the same problem.
After I had created and registered my task, it was displayed in the database as "queued" and accordingly not executed.
By manually changing it to "scheduled" it was then executed once and set back to "queued".
Of course unusable for productive use.
My error was the following:
In the services.xml I had passed additional parameters for my handler.
Accordingly my handler had a __construct() method.
However, the class inherits from "ScheduledTaskHandler" which in turn also has a constructor and expects the parameter "scheduledTaskRepository".
This repository is used to update the status.
The solution:
inject the service scheduled_task.repository in the services.xml into your custom handler
call in the construct method of the handler: parent::__construct($scheduledTaskRepository);.
In the end it should like this:
<?php declare(strict_types=1);
class myCustomHandler extends ScheduledTaskHandler
{
public function __construct(
EntityRepository $scheduledTaskRepository,
[...]
) {
parent::__construct($scheduledTaskRepository);
[...]
}
public static function getHandledMessages(): iterable
{
return [ MyCustomTask::class ];
}
public function run(): void
{
file_put_contents('test.txt', 'test');
}
}

codename one actionlistener is not calling properly in ipad device

i want to update the text field value when i was changed.for this i use action listener because every updation time one trigger was fired in my code so,that's the reason i used action listener instead of data changed listener.for data changed listener on key pressed the listener is called updation done but my requirement is after completion of entering the data on text field only the listener is called.but it is not calling properly.
please find the below code,
agencyWorker.addActionListener(createAgencyActionListener(agencyWorker,eventPostchedules.getSerialId()));
private ActionListener createAgencyActionListener(final TextField searchField, String serialId){
return new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
String agencyText = searchField.getText();
searchField.setPreferredW(110);
roasterDao = RoasterDao.getInstance();
roasterDao.updateEventPostScheduleAgency(agencyText, serialId, "supervisor");
}
};
}
thanks in advance.
I just tested this on my iPad and action listener was invoked as expected. Check that you don't have a different error that is causing this e.g. networking error related to https change in iOS.
FYI on a side note, it's really bad to write this:
searchField.setPreferredW(110);
You are limiting the size of the field based in pixels which is rarely the right thing to do. The method is deprecated for a reason...

Orchard ContentPart OnCreating Event

I'm writing a custom ContentHandler for a custom ContentPart. I was trying to use the OnCreating lifecycle event to set a value on my ContentPart before the new record was inserted into the database, but it appears that the record is created prior to my event handler being called.
public class MyPartHandler: ContentHandler
{
public MyPartHandler(
IClock clock,
IRepository<MyPartRecord> repository)
{
this.Filters.Add(StorageFilter.For(repository));
OnCreating<CustomerPart>((CreateContentContext context, MyPartRecord myPart) =>
{
myPart.CreatedUtc = clock.UtcNow;
});
}
}
Worth noting that the result is the same except that an extra database UPDATE is involved.
A few questions:
Is my observation accurate that the OnCreating event happens after the part record is inserted into the database?
If so when exactly does this event occur?
Are the lifecycle events documented anywhere in any detail? I see a list of them here http://docs.orchardproject.net/Documentation/Understanding-content-handlers#LifecycleEvents but without any real desription of when they occur.
You can use the OnActivated event. It is the first event called in the content item lifecycle.

Accessing WinForm UI from Rhino Service Bus consumer [duplicate]

This question already has answers here:
Invoke or BeginInvoke cannot be called on a control until the window handle has been created
(8 answers)
Closed 9 years ago.
I have a WinForm screen that is also a message consumer (using Rhino ESB). If I try to update anything on the screen when I receive a message, nothing happens. A call to Invoke gives me an error that the handle is not created. The form is definitely created though, I'm firing a message on button click on the form and the background process sends a message back. It's with this return message I want to update the UI.
THIS IS NOT A DUPLICATE QUESTION, NONE OF THE SUGGESTED SOLUTIONS WORK.
I believe the difference here may be because I'm using Rhino Service bus. Rhino may be constructing a separate instance of my form rather than the one I'm using. I think what I probably need to do is to have Rhino use my instance of the form as the consumer by passing my instance into the IoC container Rhino is using. Another alternative is to move the Consumer off to it's own class and inject my Form into the consumer, and put a public method on my Form for the Consumer to use. This may work fine with my app because this is the main form and will never be disposed unless the app is closed. This would become problematic on another form that may be instantiated multiple times. Perhaps I could have my form "observe" another static object that a separate Consumer class updates. Please give suggestions as to the best approach.
public partial class MainForm : Form, ConsumerOf<MoveJobCompletedEvent>
{
public void Consume(MoveJobCompletedEvent message)
{
// This does nothing!
txtLogs.Text = "\nJob completed!";
}
}
This throws an error:
this.BeginInvoke((MethodInvoker)delegate
{
txtLogs.Text += "\nJob job completed!";
});
ERROR: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
It seems that you're consuming a JobCompleted event before the window handle is created. You could try the following:
public partial class MainForm : Form, ConsumerOf<MoveJobCompletedEvent>
{
public void Consume(MoveJobCompletedEvent message)
{
if (!this.HandleCreated)
return;
this.BeginInvoke((MethodInvoker)delegate
{
txtLogs.Text += "\nJob job completed!";
});
}
}

Data binding with plugins using MEF?

I have an application that has a class named: UploadItem. The application creates uploading tasks based on information it has, for example, an upload needs to be created to upload a file to sitex.com with this the application creates a new UploadItem and adds that to an ObservableCollection, the collection is bound to a listview.
Now comes the part that I cannot solve.. I decided to change the structure so that people can create their own plugins that can upload a file, the problem lies with the fact that the UploadItem class has properties such as:
string _PercentagedDone;
public string PercentageDone
{
get { return _PercentagedDone; }
set { _PercentagedDone = value + "%"; NotifyPropertyChanged("PercentageDone"); }
}
But the plugin controls on how a file is uploaded, so how would the plugin edit the PercentageDone property that is located in the UploadItem class? If there is no way to do such a thing, then is there another way to achieve the same, i.e. showing the progress on the main GUI?
You'll want to define an interface for the plugins. Something like:
public interface IUploadPlugin
{
Task<bool> Upload(IEnumerable<Stream> files);
int Progress { get; }
}
The plugins then need to implement this interface and export themselves:
[Export(typeof(IUploadPlugin))]
public class MyUploader : IUploadPlugin, INotifyPropertyChanged
{
// ...
}
Notice that this plugin implements INotifyPropertyChanged. This is an easy way to handle updating the progress. Fire PropertyChanged on the Progress property and then databind your ProgressBar control in the main view to this property. Make sure that you fire PropertyChanged on the UI thread.
Another option would be to fire a custom event when the property changes. You could handle this event in the main view logic and update the progress.
Notice that I'm using Task for the return. This allows the caller to wait until the upload task finishes. You could use a callback instead, but with the CTP of the next version of .NET, using Task<> will allow you to use the await keyword for your async programming. Check it out here and here.

Resources