can i pass the value for IAwaitable<bool> - c#

I have a bot application where i have the below method, which i want to call explicitly in specific case rather than waiting for user input. i have the context object but how can i pass the true here
//Method code
private async Task ReadItemName(IDialogContext context, IAwaitable<true> result)
{
//
}
//Calling method: ReadItemName(context, true);
something like this but it does not accept true, but i want to pass iAwaitable type?

You can use AwaitableFromItem<T>:
ReadItemName(context, new AwaitableFromItem(true));
See doc here: https://learn.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.dialogs.awaitablefromitem-1?view=botbuilder-dotnet-3.0

Related

How to stop a function midway and let the caller performs some tasks, get the result and proceed with rest of the function's job in C#

My current scenario is that, I am writing a library in C# that performs some task. But the tasks will need to run first, then halfway, it needs some input from the caller before it can continue with the rest of the tasks in the same function. How can I achieve this sort of scenario as I am not sure what is the keyword that I should search for.
For example in the library there is a function:
public bool DoSomething()
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
// the caller now needs to perform a job and return a result before the library function can proceed
// the caller is the application consuming the library
string result = SomeWorkToBeDoneByCaller(); // ***How to achieve this?
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
You could pass in a Func<string>callback parameter:
public bool DoSomething(Func<string> someWorkToBeDoneByCaller)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
// the caller now needs to perform a job and return a result before the library function can proceed
// the caller is the application consuming the library
string result = someWorkToBeDoneByCaller();
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
Then the call would look like:
libobj.DoSomething(() => "foo");
or
libobj.DoSomething(MyFunc);
string MyFunc() { return "foo"; }
More about Func<T> here: https://learn.microsoft.com/en-us/dotnet/api/system.func-1
There are a few ways to achieve this. One is to feed the caller into the method
public bool DoSomething(MyClass callerClass)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
string result = callerClass.SomeWorkToBeDoneByCaller();
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
I've used the above pattern for a few things, depending on your use case it can do the trick (depending on the nature of the work I'd reccomend making it async too but that's a whole other thing)
Another way is to pass in delegate methods (change the <> arguments to change the method's signature, and use Action if the method returns void)
public bool DoSomething(Func<ReturnClass,string,string> methodFromCallerClass)
{
SomeWorkToBeDoneByLibrary_1();
SomeWorkToBeDoneByLibrary_2();
SomeWorkToBeDoneByLibrary_3();
string result = methodFromCallerClass("foo","Bar");
SomeWorkToBeDoneByLibrary_4(result);
SomeWorkToBeDoneByLibrary_5(result);
SomeWorkToBeDoneByLibrary_6(result);
return true;
}
and you can use linq to make passing in the delegate easier if the signatures don't match 100% something like (x,y) => Foo(x,y,"bar") changes the method from having three parameters to two

Method to wait until element is displayed, but need to pass the element as a parameter to make it a generic method to be used

I want to create a generic method to be used across the test suite. This method should take the web element as a parameter. Then the method should return true or false based on the visibility of it during the configured time out.
public bool WaitForElementVisibility(IWebDriver driver, IWebElement element)
{
try
{
//code to wait until element is displayed similar to this. But instead of passing By.Id(login) pass the element
new WebDriverWait(driver,TimeSpan.FromSeconds(timeOut)).Until(ExpectedConditions.ElementExists((By.Id(login))));
return true;
}
catch(Exception e)
{
return false;
}
}
I'm creating a framework in selenium, C#.
You can see my progress in this https://umangamadawala.blogspot.com/.
Thanks in advance.
I think that you are searching something like this code:
You can pass your By.Id("Login") as a By element without any problem, so the call to this function will be something like:
WaitUntilElementVisible(By.Id("Login")); and if you want to change in this call the timeout time you will call like this: WaitUntilElementVisible(By.Id("Login"),45);
You cam put there your Try and catch logic. I use ElementIsVIsible but you can use ElementExist only changing the call.
protected virtual IWebElement WaitUntilElementVisible(By elementLocator, int timeout = 30)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout));
return wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(elementLocator));
}

How are methods with arguments invoked?

I am trying to call a method with arguments, but it doesn't work. I have this method:
public class AllMethods
{
//method change state and status of entity objetivovisitacao for "Propagado"
public static void changeStatus(Guid objetivoId, IOrganizationService service, int state)
{
SetStateRequest setStateRequest = new SetStateRequest
{
EntityMoniker = new EntityReference("statuscode", objetivoId),
State = new OptionSetValue(0),
Status = new OptionSetValue(911950001),
};
service.Execute(setStateRequest);
}
}
And I need to call that method, so I tried doing it this way:
AllMethods.changeStatus();
But it's wrong. Can someone explain this so that I can better understand what I'm missing here?
First create variables for the parameters of the method. Then pass them in the same order as they was declared in the method.
Guid yourObjetivoId = new Guid();
IOrganizationService yourService = New YourImplementationOfOrganizationService();
int yourState = 3;
AllMethods.changeStatus(yourObjetivoId, yourService, yourState);
From MSDN: Methods (C# Programming Guide)
The method definition specifies the names and types of any parameters
that are required.
When calling code calls the method, it provides
concrete values called arguments for each parameter.
The arguments
must be compatible with the parameter type but the argument name (if
any) used in the calling code does not have to be the same as the
parameter named defined in the method
No need to state the types of the parameters when passing them through.
You should call it like this:
AllMethods.changeStatus(objetivoId, service, state);
you need to pass the parameters, see documentation: Pass parameters c#
in your case
AllMethods.changeStatus(objetivoId, service, state);
If you declare a method like you did:
public static void changeStatus(Guid objetivoId, IOrganizationService service, int state)
you declare parameters in the parentheses. The compiler expects the necessary input when you try to call it. So you need the fitting parameters for the call of this method. It is like a key to a lock.
Guid objetivoId = // your value
IOrganizationService service = // your value
int state = // your value
then you call it like this:
AllMethods.changeStatus(objetivoId, service, state);
You don't need to declare them again in the call! it has to be done beforehand
You are doing it wrong since, you are declaring the types of the parameter here:
AllMethods.changeStatus(Guid objetivoId, IOrganizationService service, int state);
for calling this method changeStatus(...), you need to pass the variable for the parameters objetivoId, service, state.
AllMethods.changeStatus(objetivoId, service, state);
See: Passing of Parameters in C#
MSDN:
In C#, arguments can be passed to parameters either by value or by
reference.

How to get method results with AsyncCallback?

I hope you can help me with the following:
I have a WebService method which is supposed to return an array of CompensationPlanReturnReturn objects.
The method is called like this:
//This is the object I need to instanciate because it contains the method I wanna call
CompensationPlan_Out_SyncService test = new CompensationPlan_Out_SyncService();
//This is the method that is supposed to return me an array of CompensationPlanReturnReturn objects
//The data.ToArray() is the parameter the method need, then I pass the method that I wanna run when the method finishes and I dont know what to pass as the final parameter
test.BeginCompensationPlan_Out_Sync(data.ToArray(), new AsyncCallback(complete), null)
//The method description is:
public System.IAsyncResult BeginCompensationPlan_Out_Sync(CompensationPlanDataCompensationPlan[] CompensationPlanRequest, System.AsyncCallback callback, object asyncState)
//On this method I'd like to access to the resuls (the array of CompensationPlanReturnReturn) but I dont know how
private void complete(IAsyncResult result)
{
lblStatus.Text = "Complete";
}
You need to call test.EndCompensationPlan_Out_Sync(result), which will return the result of the asynchronous operation, or throw an exception if an error occurred.
Async methods breakdown into two submethods - Begin and End.
You need to call EndCompensationPlan_Out_Sync to get the actual result returned by method -
private void complete(IAsyncResult result)
{
var actualResult = test.EndCompensationPlan_Out_Sync(result);
lblStatus.Text = "Complete";
}
Try to use the AsyncState-Property and cast it the the given Type.
Like this:
cSACommand = (SACommand)Result.AsyncState;

How to pass an action to task factory with weak reference to target

Edit: I updated my code. Would this achieve what i am aiming for?
I have a working set of methods for async calling of methods but i have a specific problem with the references i pass in via a lambda. Specifically i have a (child) window that starts an operation and registers a callback. As you might expect, even when i close this window it still gets invoked.
What i want to do is pass in a kind of "weak reference" or construct a weak reference out of the incoming action.
Thhis is the way i build my Action (example code):
static Action CreateNewAction(Action call, Action<SomeArg> callback,
Dispatcher dispatcher)
{
return delegate {
try
{
call();
var target = callback.Target
if(target != null)
dispatcher.Invoke(callback, new SomeArg());
}
catch (Exception ex)
{
// handle the ex in some way..
}
};
}
And this is how the task factory calls it:
var t = Task.Factory.StartNew(CreateNewAction(call, callback, dispatcher))
And this is how I would call it (the call just basses both the action and the callback through to the task factory as seen above):
WeakReference wr = new WeakReference(myTarget);
StartMyTaskAsync(someAction, ((MyTargetClass)wr.Target).SomeCompletedFunc);
The problem comes from this line:
StartMyTaskAsync(someAction, ((MyTargetClass)wr.Target).SomeCompletedFunc);
Specifically, this part:
((MyTargetClass)wr.Target).SomeCompletedFunc
You are materializing the target of the WeakReference to get the method that is referenced by the lambda/delegate long before you want to actually check whether or not the WeakReference has let go of the Target.
What you really want to do is pass a wrapper for your delegate, something like this (you didn't show the signature of SomeCompletedFunc so I don't know exactly what the call will be like, I'm assuming it's a parameterless void method for the purposes of this question):
StartMyTaskAsync(someAction, () => {
// Check the weak reference. If null, return.
var target = wr.Target as MyTargetClass;
// If null, return.
if (target == null) return;
// If not null, call.
target.SomeCompletedFunc();
});
This way, you check the Target of the WeakReference at the time you want to make the method call, and not when you assign the callback.

Categories