I have hosted a WCF service in windows service. I have console app for which I added a WCF service reference and generated Client for it.
I can make Sync call to the service,but Async call doesn't seem to work. If i attach server process it doesn't hit the service at all.
client= new ServiceClient();
client.DoSomething();//Works fine
client.DoSomethingAsync()//Doesnot work
Is this a known problem?
The asynccall will probably be started in a background workerthread. So what could be happening is that your async thread is dieing out because the foreground thread has finished it's processing.
Unless you have some logic after you make this call to wait for the reponse, or continue with some other work on your main thread, the background thread may not have the time to get created before the application exits.
This can be easily tested by adding Thread.Sleep after the async call.
client.DoSomethingAsync();
Thread.Sleep(1000);
A symptom of this happening is that your service starts / stops unexpectedly and windows throws an error.
When you generated the client, did you tick the box to specify "Generate asynchronous operations"?
From the code posted, i'm assuming you have not set up handlers to deal with the response from the async method. You'll need something like the example at the bottom of this msdn post where you use AddHanlder to handle the response.
Something like the below before you make the async call:
AddHandler client.DoSomethingCompleted, AddressOf DoSomethingCallback
With a method to deal with the outome:
Private Shared Sub DoSomethingCallback(ByVal sender As Object, ByVal e As DoSomethingCompletedEventArgs)
'Do something with e.Result
MsgBox e.Result
End Sub
If you have a call to
client.DoSomethingAsync()//Doesnot work
then did you specify a handler for the callback completed event??
public event DoSomethingCompletedEventHandler DoSomethingCompleted;
What happens is that the async call goes off, but how would it send you back any results?? You'll need to provide a handler method for that - hook it up to the DoSomethingCompleted event handler! In that method, you'll get the results of the async call and you can do with them whatever you need to do.
Marc
Related
I'm trying to run some functions alongside the pyrogram client as an event listener application. I tried the following code, but the handler was never invoked. I guess it is because the event loop does not dispatch the while loop, so the thread was never released back to run the handler. but is there a way to properly do this?
async def run_tele():
app.add_handler(MessageHandler(handle, filters=filters.text))
await app.start()
while True:
# do something here
time.sleep(1)
await app.stop()
if __name__ == '__main__':
app.run(run_tele())
You're starting the client (app.start()), but never actually give it an opportunity to listen for events. Call pyrogram.idle() so that Pyrogram keeps the Client alive and listens for updates from Telegram.
Alternatively you can also use app.run(), which will start(), idle(), and stop() for you.
I'm working on a program that should find some image's urls from a website and should download them, i already wrote the parsing code and the downloading code, and it work, but since i noticed it's really slow i thought that it would be better if i make it work async from the form, so i created 2 background worker:
1) The parser
2) The downloader
When the parser starts the downloader starts too, the parser should add urls to a listbox, and the downloader should download them and delete from the list, i don't think it will be a problem to manage that, my real problem is... that i never used background worker...
The parser should load the page in a Webbrowser, than parse the images, but when i call the function navigate on the webbrowser... it stop giving me a TargetInvocationException.
I searched online, and from what i have seen it seems that backgrond workers cannot directly access to proprieties and methods of the GUI controls, from what i've understand it shold use Invoke, so i created a function that do all the work, and it check if the browser is in another thread or is in this thread by doing this:
Sub parse(ByVal url As String)
If wb.InvokeRequired Then 'wb is the Webbrowser
wb.Invoke(New Action(AddressOf prova))
Return
End If
'Navigate to the url, wait for browser to complete loading then do the parsing
End Sub
Now my problems are two:
1)The invokerequired propriety value is false even if i call the method from the worker, so the invoke is not called and it still give me the same exception
2)If i call invoke i should force the method to run in the GUI thread, right?
If so... shouldn't it slow my program as before?
I did it alone, the problem was that i created the components in runtime, so I should have created the handles for the components, it was enough to do something like this after creating the components:
If Not wb.IsHandleCreated Then
Dim handle As IntPtr = wb.Handle
End If
The variable handle is useless, but calling the handle propriety of the component it force the component to create the handle, that's why I made that assignment.
When i try to view MDIParent screen in designer mode I’m getting below exception...
`Could not find endpoint element with name 'NetTcpBinding_IMyService' and contract 'ClientProxy.IMyService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.'
Little background to understand my question more clearly...
I've a WCF server which I’m trying to consume in my Winform application. So i've created a separate class library in which i added service reference and created a proxy. I've copied the client endpoint info from app.config in class library to UI app.config file.
When i run the application everything is working fine but when i try to open MDIParent screen in designer mode its throwing above exception.
Note: I think i'm getting error because i'm trying to create a proxy object on NEW method (form constractor) if i comment that line - i'm able to view designer screen.
Please help :)
Venky
If you instantiate the service in the form's constructor, this could be the source of your problem.
If this is the case, wrap the service initialization in a test for DesignMode:
If Not Me.DesignMode Then
' Initialize service
End If
Update
It turns out that DesignMode is not supported in the constructor.
There are a couple of workarounds to choose from:
1) Use the following instead of the designmode test:
If System.ComponentModel.LicenseManager.UsageMode <> System.ComponentModel.LicenseUsageMode.Designtime Then`
2) Move your initialization code from the constructor into the Form's _load event and then use the DesignMode test.
Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
If Not Me.DesignMode Then
' Initialize service
End If
End Sub
My WinForm apps needs to execute complex query with significant execution time, I have no influence (about 10mins)
When query is executing user sees 'application not responding' in task manager, which is really confusing to user, also not very professional...
I believe that query shall be executed in different thread or so. Have tried some approaches but have difficulties to make it really working (execute query, force main application wait result, return back to main app, possibility to cancel execution etc)
I wonder if you have own / good working solution for that. Code samples would be also very welcome :)
Also I believe there might exist some ready to use utilities / frameworks allowing simple execution of that.
The simplest approach here would be to do that work from a BackgroundWorker. MSDN has examples for this. This then executes on a worker thread, with events for completion/error/etc. It can also support cancel, but your operation needs to be coded to be interruptable.
Another approach is the Task API in 4.0; but if you use this you'll need to get back to the UI thread (afterwards) yourself. With BackgroundWorker this is automatic (the events are raised on the UI thread).
If ExecuteQuery if the method you want to execute, you can do:
void SomeMethod() {
var thread = new Thread(ExecuteQuery);
thread.Start();
}
void ExecuteQuery() {
//Build your query here and execute it.
}
If ExecuteQuery receives some parameters, like:
void ExecuteQuery(string query) {
//...
}
You can do:
var threadStarter = () => { ExecuteQuery("SELECT * FROM [Table]"); };
var thread = new Thread(ThreadStarter);
thread.Start();
If you want to stop the execution of the background thread, avoid calling thread.Abort() method. That will kill the thread, and you do not want this, because some incosistency could appear in your database.
Instead, you can have a bool variable visible from ExecuteQuery and from outside you can set it to True when you want to stop it. Then all you have to do is check in some parts of the code inside ExecuteQuery if that variable is still True. Otherwise, do some rollback to maintain the database stable.
Be sure you set that bool variable volatile
Edit:
If you want the UI to wait from the background thread, I usually do:
Start the background thread
Start some progress bar in the UI
Disable some controls (like buttons, etc) to avoid the user to click them while the background thread is working (eg: If you're executing the thread when a user clicks a button, then you should disable that button, otherwise multiple queries will be ocurring at the same time).
After finished the thread, you can stop progress bar and enable controls again.
How to know when the thread finished? You can use Events for that. Just create an event and fire it when it finishes, and do whatever you want inside the event handler...
Be sure you're accessing correctly to UI controls from the background thread, otherwise it will give you an error.
If you are new to threads and task is simple (as it seems), you should try to use standard background worker component.
I have a GUI class and a database class. I do something like:
Dim db as Database = getDatabaseObject(logTxtBox)
db.executeNonQuery("some update command here")
Within executeNonQuery I connect to the db, execute the command, disconnect and catch the exceptions. logTxtBox is the GUI txt box I want log messages written to. Currently it writes something like:
Connected to DB successfully
Executing "some update command here"
Excepetion: ........
Disconnecting from DB
I feel like this isn't the best structure for my logging. As soon I kick off executeNonQuery with a BackgroundWorker instead of with the main GUI thread I cannot access the GUI's logTxtBox from the BackgroundWorker's thread.
Is there a better way to implement this kind of functionality?
Thanks-
Jonathan
To use a UI component from a background thread make sure you use Control.Invoke() to make sure the code runs in the UI thread.
Here's some C# code that calls a method on the UI thread and passes in a parameter:
this.Invoke(new Action<string>(MyMethod), "something to log");
private void MyMethod(string logData) {
// set some text here
}
You could raise events in within your database class an handle those events in the ui. For example you could create a custom "StatusChanged" event and pass the current state within the eventargs.