1

I need to migrate a WinForm Application to a Console Application.

In the WinForm Application, I have something like:

this.Invoke(new LogResponseCallback(this.LogResponse), new object[] { allAlarmsJson });


   private delegate void LogResponseCallback(string text);
    private void LogResponse(string response)
    {
        this._richTextResponse.Text = response + "\r\n";
    }

Seems like Main Thread has been called after the processing of a certain operation.

My concern is how can the same Asynchronous delegate call can be achieved in the Console application.

Any help would be highly appreciated.

Thanks in advance

CuriousBuddy
  • 179
  • 1
  • 8
  • 21
  • You can't, a console app doesn't have the required plumbing to make a SynchronizationContext derived class work. Making your own essentially involves re-inventing the message loop. It is much less of a problem in console apps because the Console class is already thread-safe. Avoid using RichTextBox in a console app, it tends to create its window handle when you manipulate its Rtf property. That is not good. – Hans Passant Aug 10 '11 at 14:54

3 Answers3

1

Here is a question I asked about how Invoke does what it does,

Curious about the implementation of Control.Invoke()

Community
  • 1
  • 1
Kratz
  • 4,280
  • 3
  • 32
  • 55
0

Normally in Windows Forms you'd use Control.Invoke to get back to the UI thread from a background thread, as you can't access UI controls within a non-UI thread.

The same restriction doesn't apply in a console application - you may still need to be careful to avoid threading issues, but they're unlikely to be the same issues. If all you're doing is logging to the console (e.g. with Console.WriteLine) you should be fine to just do the logging in the background thread.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks guys for the help. I have few concerns: Does that mean that I can call the method( as here it is LogResponse) directly in my Console Application. Also what is basically done in the Windows Appliation is it send Http request and receive the response continuously. How can I acheive that ? – CuriousBuddy Aug 11 '11 at 06:17
  • @user739990: The LogResponse method appears to be using a UI control... presumably you won't be doing that any more, so what *will* you be doing. It's not clear what you mean by "receive the response continuously" - do you need multiple concurrect requests, or are you just happy to loop, fetching data and logging it? – Jon Skeet Aug 11 '11 at 06:20
  • There are many methods that ar called in the WinForm applcaition via Control.Invoke() To answer your second question .The code uses this this._timer = new System.Threading.Timer(new TimerCallback(GetRealtimeUpdates), null, -1, -1); – CuriousBuddy Aug 11 '11 at 06:51
  • private string GetRealtimeUpdates (string requestUrl) { // lock an object to make sure request/response from different threads do not step on themselves lock (this._cookieContainer) { // prepare the request webRequest = (HttpWebRequest)WebRequest.Create(requestUrl); webResponse = (HttpWebResponse)webRequest.GetResponse(); } this.Invoke(new LogResponseCallback(this.LogResponse), new object[] { allChannels}); } – CuriousBuddy Aug 11 '11 at 06:52
  • Seems like there is a thread call. The data comes via HTTP request and in the application GUI the grid keeps on populating with the data after every few seconds. – CuriousBuddy Aug 11 '11 at 06:53
  • @user739990: Don't focus on what the WinForms application *currently* does. Focus on what the new console application is *meant* to do - and then edit your question to make that clear. – Jon Skeet Aug 11 '11 at 07:23
  • Work of this Winform Application is to send the Https request and get the response. This is RealTime which has been implemented via code this._timer = new System.Threading.Timer(new TimerCallback(GetRealtimeUpdates), null, -1, -1); code – CuriousBuddy Aug 11 '11 at 07:53
  • Apart from this there are delegates calls inside the WinForm applcation using 'code' this.Invoke(new LogResponseCallback(this.LogResponse). I know this is for invoking it back in UI thread. So, Should I substitute such calls in Console application by simply calling methods (of those delegates)? – CuriousBuddy Aug 11 '11 at 07:54
  • @user739990: You *keep* talking about what the Windows Forms app is doing about callbacks etc - if you could just explain what you want the *console* app to do in terms of concurrent requests etc, it would be a lot clearer. You may well not need delegates at all - you *may* be fine just in a single thread. We don't know, because we don't know what your app is meant to do. – Jon Skeet Aug 11 '11 at 07:55
  • I need to make a http request and put the response in a structered way inside a CSV file. This request will be made multiple times running independently. – CuriousBuddy Aug 11 '11 at 10:05
  • @user739990: "Running independently" as in "at the same time"? Is each request creating a separate CSV file? Where do you want to log output? – Jon Skeet Aug 11 '11 at 10:13
  • yes.Correct. They will execute concurrently.By Independently I meant, Not disturbing other ongoing threads. All I have is the WinForm applcation to understand the requirement in which these calls are made using System.Threading.Timer(new TimerCallback(GetRealtimeUpdates), null, -1, -1); . All request will put the data inside a single CSV file. Thanks – CuriousBuddy Aug 11 '11 at 11:05
  • @user7399990: If you've got lots of requests all writing into the same CSV file, how are you expecting that to be coordinated? It sounds like you probably only *actually* have one of these requests at a time, triggered by a timer. Please come up with a detailed description of what you need and edit it into the question - preferably with little or no reference to the WinForms application. – Jon Skeet Aug 11 '11 at 11:12
  • I have an option there. I can put it inside a database as well. and just to get clarification, in case of CSV, Can't I put it inside a lock(). – CuriousBuddy Aug 11 '11 at 14:06
0

First of all you are not using any asynchonous delegate in your code here, the this.Invoke is synchronous call.
Second if you are running Console application you don't have to marshal the call back to the main thread, You only should do so when you are executing code that relying on thread, such as winforms, wpf UI thread and some COM components, you only have to marshal call in these situations because these components are relying on the thread that created them

Jalal Said
  • 15,906
  • 7
  • 45
  • 68
  • Does that mean that I can call the method( as here it is LogResponse) directly in my Console Application. Also what is basically done in the Windows Appliation is it send Http request and receive the response continuously. How can I acheive that ? – CuriousBuddy Aug 11 '11 at 06:22
  • I don't know what is the relashion ship between your `_richTextResponse` winform UI control and your Console application? If you want to run console application then you don't need to log using `_richTextResponse` because it is a windows forms UI control and it doesn't related to console application. However what are you trying to achieve here? if you are running a windows forms application, you can start Console application from it. check [this link](http://stackoverflow.com/questions/2593313/how-to-execute-console-application-from-windows-form) to learn how. – Jalal Said Aug 11 '11 at 06:46
  • As I mentioned earlier I need to migrate the WinForm application to Console based. Work of this Winform Application is to send the Https request and get the response. This is RealTime which has been implemented via `code` this._timer = new System.Threading.Timer(new TimerCallback(GetRealtimeUpdates), null, -1, -1); `code` – CuriousBuddy Aug 11 '11 at 07:50
  • Apart from this there are delegates calls inside the WinForm applcation using 'code' this.Invoke(new LogResponseCallback(this.LogResponse). I know this is for invoking it back in UI thread. So, Should I substitute such calls in Console application by simply calling methods (of those delegates)? – CuriousBuddy Aug 11 '11 at 07:53