Async call never returns - multithreading

please have a look at below code.
public static class DbModel
{
public static readonly int TableID = 0;
static DbModel()
{
DbModel.PodID = FetchTableID().PodID;
}
public static Pod FetchTableID()
{
Pod result = null;
try
{
//Control never comes back from this line. What am I missing?
var searchResult = apiPod.SearchTableAsync(1).Result;
result = searchResult.First();
}
catch (Exception ex)
{
Helpers.TraceException(PageName,"FEtchPodID","Unable to fetch PodID",ex);
}
return result;
}
}
Signature of SearchTableAsync looks like this
public async Task<List<Pod>> SearchTableAsync(int i)
{
try
{
using (var client = new HttpClient())
{
//deleted - connecting to server, constructing query string etc.
var response = await client.GetAsync(ApiBaseUrl + "api/Pod/Search" + queryString);
if (response.IsSuccessStatusCode)
{
var podList = await response.Content.ReadAsAsync<List<Pod>>();
return podList;
}
else
{
//log error
}
}
}
catch (Exception ex)
{
Logger.TraceError(null, ex);
}
return null;
}
Call to SearchTableAsync never returns back. Am I missing anything? Or its because I am invoking this from Static constructor?

The problem is likely due to the use of Task.Result property. this is a blocking property and can cause a deadlock. You can simply await the task which will return the result, but you need to make the method async.
public static async Pod FetchTableID()
{
Pod result = null;
try
{
var searchResult = await apiPod.SearchTableAsync(1);
result = searchResult.First();
}
catch (Exception ex)
{
Helpers.TraceException(PageName,"FEtchPodID","Unable to fetch PodID",ex);
}
return result;
}

searchResult = apiPod.SearchTableAsync(1).excute.get;
use this instead of
var searchResult = apiPod.SearchTableAsync(1).Result;

This post explains why it was blocking.
Cheers,
Hemant

Related

Nifi: how to remove session based on atribute value in nifi

I want to remove session in case i get certain data from file i have code like this,but i got errors "flowfile has already marked for removal", what should i change to get rid of extra errors?
In case of session rollback flowfile will dissapear in queues also?
2.should i use rollback instead of remove()?
NodeList childNodes = nodeGettingChanged.getChildNodes();
for (int i = 0; i != childNodes.getLength(); ++i) {
Node child = childNodes.item(i);
if (!(child instanceof Element))
continue;
if (child.getNodeName().equals("runAs")) {
if(child.getFirstChild().getTextContent()=="false"){
session.remove(flowFile1);
File deleteExtraFile =new File("C://Users//s.tkhilaishvili//Desktop//try2//nifi-1.3.0//1//conf.xml");
boolean delete=deleteExtraFile.delete();
}
else {
child.getFirstChild().setNodeValue("false");
}
}
}
Document finalXmlDocument = xmlDocument;
session.write(flowFile1, new StreamCallback() {
public void process(InputStream inputStream, OutputStream outputStream) throws IOException {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = null;
try {
transformer = transformerFactory.newTransformer();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
}
DOMSource source = new DOMSource(finalXmlDocument);
ffStream.close();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
StreamResult result = new StreamResult(bos);
try {
transformer.transform(source, result);
} catch (TransformerException e) {
e.printStackTrace();
}
byte[] array = bos.toByteArray();
outputStream.write(array);
}
});
session.remove(flowFile);
session.transfer(flowFile1, REL_SUCCESS);
}
If you are executing session.remove(flowFile1) then later trying to transfer it to REL_SUCCESS, you will get that error. It looks like you already have an if-clause checking the firstChild for "false", perhaps you could put the transfer in an else-clause, such that it will only be transferred if it wasn't removed.

IAsyncResult and Multithreading in .NET 3.5

I'm want to make multiple requests to a remote service and I'm trying an asynchronous/multithread approach.
For the concurrent part, I'll try this http://coding-time.blogspot.pt/2008/03/implement-your-own-parallelfor-in-c.html
IList<string> returnedValues = new List<string>();
int numberOfRequests = 5;
object sync = new object();
ParallelUtilities.For(0, numberOfRequests, delegate(int i)
{
string response = string.Empty;
try
{
try
{
Func<int, string> caller = CallService;
IAsyncResult result = caller.BeginInvoke(i, null, null);
Thread.Sleep(0);
string returnValue = caller.EndInvoke(result);
lock (sync)
{
returnedValues.Add(returnValue);
}
}
catch (Exception ex)
{
Console.WriteLine(string.Concat("ex: ", ex.Message, "stack:", ex.StackTrace));
}
});
}
And the service call
private string CallService(int index)
{
string value;
using (var channel = GetClientChannel<IService>("http://localhost:51383/Service/Service.svc"))
{
value = channel.GetValue(index);
}
return value + "for this index:" + index;
}
Is there a better way to do this?
How do IAsyncResult works in multithreading?
Replace
IAsyncResult result = caller.BeginInvoke(i, null, null);
Thread.Sleep(0);
string returnValue = caller.EndInvoke(result);
with
string returnValue = CallService(result);
There's no point in starting code on the thread-pool and then waiting for it immediately. What would you gain by doing that? The Sleep is especially suspicious to me. You try to initiate a context switch which just adds additional overhead.
How do IAsyncResult works in multithreading?
The two are not related. What do you mean?

Easy way to handle AcceptMessageSessionAsync and ReceiveAsync

Attempting to jump into the Windows Server ServiceBus 1.1 code-base along with adopting the new TPL async methods. But I could not find an easy way to just spin up N number of handlers for message sessions (might have 100 or so concurrent sessions). So it would be great to get some feedback on the following code, any suggestions on an easier way would be great... note tried to keep code sample simple for the questions purpose.
///example usage
SubscriptionClient subClient = SubscriptionClient.Create(TopicName, SubscriptionName);
subClient.HandleSessions(5, msg =>
{
Console.WriteLine(string.Format("Processing recived Message: SessionId = {0}, Body = {1}",
msg.SessionId,
msg.GetBody<string>()));
msg.Complete();
});
public static class SubscriptionClientExtensions
{
public static void HandleSessions (this SubscriptionClient sc, Int32 numberOfSessions, Action<BrokeredMessage> handler)
{
Action<Task<MessageSession>> sessionAction = null;
Action<Task<BrokeredMessage>> msgHandler = null;
sessionAction = new Action<Task<MessageSession>>(tMS =>
{
if (tMS.IsFaulted) // session timed out - repeat
{
sc.AcceptMessageSessionAsync().ContinueWith(sessionAction);
return;
}
MessageSession msgSession = null;
try
{
msgSession = tMS.Result;
}
catch (Exception)
{
return; // task cancelation exception
}
msgHandler = new Action<Task<BrokeredMessage>>(taskBM =>
{
if (taskBM.IsFaulted)
return;
BrokeredMessage bMsg = null;
try
{
bMsg = taskBM.Result;
}
catch (Exception)
{
return; // task cancelation exception
}
if (bMsg == null)
{
sc.AcceptMessageSessionAsync().ContinueWith(sessionAction); // session is dead
return;
}
handler(bMsg); // client code to handle the message
msgSession.ReceiveAsync(TimeSpan.FromSeconds(5)).ContinueWith(msgHandler); // repeat
});
msgSession.ReceiveAsync(TimeSpan.FromSeconds(5)).ContinueWith(msgHandler); // start listening
});
for (Int32 nIndex = 0; nIndex < numberOfSessions; nIndex++)
{
sc.AcceptMessageSessionAsync().ContinueWith(sessionAction);
}
}
}

Video capturing issue

I want to create a LWUIT Image from the captured video. The problem is that the MediaException is raised when calling getSnapshot() :
private void showCamera() // called when clicking the "open camera" command
{
try
{
Player mPlayer;
VideoControl mVideoControl;
mPlayer = Manager.createPlayer("capture://video");
mPlayer.realize();
mVideoControl = (VideoControl) mPlayer.getControl("VideoControl");
Canvas canvas = new CameraCanvas(this, mVideoControl, mPlayer, getFirstAvailableRoot(), "ADC"+adcId); // adcId is "1"
isFromPositionnement = true; // static variable
javax.microedition.lcdui.Display.getDisplay(controler).setCurrent(canvas);
mPlayer.start();
} catch (IOException ex) {
handleException();
} catch (MediaException ex) {
handleException();
}
}
private String getFirstAvailableRoot()
{
short iter;
String root = "Phone:/";
iter = 0;
Enumeration drives = FileSystemRegistry.listRoots();
while(drives.hasMoreElements() && iter < 1) {
root = String.valueOf(drives.nextElement());
iter++;
}
return root;
}
Code in "CameraCanvas" :
public class CameraCanvas extends Canvas implements CommandListener
{
...
public CameraCanvas(Ecran form, VideoControl videoControl, Player pPlayer, String pRoot, String dossierPhoto)
{
...
mCaptureCommand = new Command("Capturer", Command.SCREEN, 1);
addCommand(mCaptureCommand);
setCommandListener(this);
...
videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);
try
{
videoControl.setDisplayLocation(2, 2);
videoControl.setDisplaySize(width - 4, height - 4);
}
catch (MediaException me)
{
try
{
videoControl.setDisplayFullScreen(true);
}
catch (MediaException me2)
{}
}
videoControl.setVisible(true);
}
private void capture() // called when clicking the mCaptureCommand command
{
try
{
isPhotoCaptured = true;
rawImg = vidCtrl.getSnapshot(null); // this throws the exception
vidCtrl.setVisible(false);
vidCtrl = null;
mPlayer.close();
mPlayer = null;
repaint();
}
catch (MediaException me)
{
isPhotoCaptured = false;
rawImg = null;
vidCtrl.setVisible(false);
vidCtrl = null;
mPlayer.close();
mPlayer = null;
handleException("capture ");
}
}
}
So what may be the cause of the issue ?
MMAPI has the ability to create an image and you can easily turn it to a LWUIT image (which has a create image that accepts an object). However, for some reason the "geniuses" who came up with this API made image capture a restricted API to protect your privacy. So effectively you can't invoke this API without an operator/manufacturer signature.

Not able to get DirContext ctx using Spring Ldap

Hi i am using Spring ldap , after execution below program It display I am here only and after that nothing is happening, program is in continue execution mode.
public class SimpleLDAPClient {
public static void main(String[] args) {
Hashtable env = new Hashtable();
System.out.println("I am here");
String principal = "uid="+"a502455"+", ou=People, o=ao, dc=com";
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "MYURL");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, principal);
env.put(Context.SECURITY_CREDENTIALS,"PASSWORD");
DirContext ctx = null;
NamingEnumeration results = null;
try {
ctx = new InitialDirContext(env);
System.out.println(" Context" + ctx);
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
results = ctx.search("", "(objectclass=aoPerson)", controls);
while (results.hasMore()) {
SearchResult searchResult = (SearchResult) results.next();
Attributes attributes = searchResult.getAttributes();
Attribute attr = attributes.get("cn");
String cn = (String) attr.get();
System.out.println(" Person Common Name = " + cn);
}
} catch (NamingException e) {
throw new RuntimeException(e);
} finally {
if (results != null) {
try {
results.close();
} catch (Exception e) {
}
}
if (ctx != null) {
try {
ctx.close();
} catch (Exception e) {
}
}
}
}
}
Try fixing the below lines, i removed "ao" and it works fine.
results = ctx.search("", "(objectclass=Person)", controls);
You need to give search base as well
env.put(Context.PROVIDER_URL, "ldap://xx:389/DC=test,DC=enterprise,DC=xx,DC=com");
Refer this link as well http://www.adamretter.org.uk/blog/entries/LDAPTest.java

Resources