I have a synchronous task but sometime thread get stuck while making a remoting call which blocks the execution. So I want to make remote call making part async using a ThreadPool thread , but my idea is to keep it synchronous as much possible, that is I want main thread to wait for a timout value or ThreadPool thread to complete ,so that this activity is asynchronous only in case of thread stuck.
ThreadPool thread doesn't give any handle so that I can call thread.join(timeout) on that and I can't use autoreset events also as that part of code can be accessed by multiple threads so which thread sets / resets autoreset event becomes even complicated and also it is an overhead.
Can you please suggest a cleaner way for this problem ?
I can't create Thread also using Thread class because as I mentioned above that area of code can be accessed by multiple threads and it is a small task that remote call does ,something like updating a text like progress .
Code Snippet:
public static Exception AddProgress(Session session, ITaskSetProgress progress)
{
IIconUIServer server = IconRemotingServer.Instance.GetUiServer(session);//gets remote proxy object
server.AddProgress(progress);// calls a method over remoting IPC channel
}
And this method can be called by more than one thread at a time.
My intention is to write AppProgressAsync method ,so that when call server.AddProgress(progress); hangs then only it should behave as async ,so I have a timeout .
I can't use Task Library as I need to support old customers who are on .net 3.5 still.
I solved this issue by using async delegates :something like below:
public static void AddProgressAsync(Session session, ITaskSetProgress progress)
{
AddProgressDelegate addProgress = new AddProgressDelegate(AddProgress);
try
{
IAsyncResult result = addProgress.BeginInvoke(session, progress, null, null);
result.AsyncWaitHandle.WaitOne(timeoutValue);
}
catch (Exception ex)
{
}
finally
{
addProgress = null;
}
}
public static void AddProgress(Session session, ITaskSetProgress progress)
{
IIconUIServer server = IconRemotingServer.Instance.GetUiServer(session);//gets remote proxy object
server.AddProgress(progress);// calls a method over remoting IPC channel
}
It works fine in this scenario !!
Related
My understanding is that if you call async code synchronously it can cause deadlock when it needs to synchronize back to the UI thread to modify UI elements or if you need to access ASP.NET HttpContext.Current. There are workarounds to solve this problem as mentioned here:
https://learn.microsoft.com/en-us/archive/msdn-magazine/2015/july/async-programming-brownfield-async-development
How to call asynchronous method from synchronous method in C#?
I was looking at the "The Thread Pool Hack" approach from the first link but I need to call GetAwaiter().GetResult() directly from the async code which is already called from a new thread e.g:
//MyWork.DoWork must execute in a separate thread due legacy code that I can't refactor right now.
public class SomeClass {
try {
var myThread = new Thread(MyWork.DoWork);
myThread.Start();
} catch (Exception ex) {
//Handle exceptions
}
}
public class MyWork {
public static bool DoWork(){
var response = MyHttpClient.MakeRequestAsync(params)
.GetAwaiter()
.GetResult();
if(!response.Succeed){
//add logs and other stuff
}
}
}
Also my call to MyHttpClient.MakeRequestAsync is NOT using .ConfigureAwait(false); and I can't add that since the same calls can be used in other places where it may need to synchronize back to the UI context
Is it safe to call .GetAwaiter().GetResult() directly on MyHttpClient.MakeRequestAsync since I'm already starting the work in a separate thread?
Once the MyHttpClient.MakeRequestAsync resumes will it resume the work in the same thread?
Update:
I cannot let the async pattern propagate I must use existing legacy code that uses the thread class so no refactoring allowed at the moment for SomeClass.
One of the things I'm having a hard time to understand in multi-threaded programming is that fact that when one thread reaches a line that calls WaitOne(), how do I know which other threads are involved? Where or how can I find (or understand) how the WaitHandle receives the signal? For example, I'm looking at this code right now:
private void RunSync(object state, ElapsedEventArgs elapsedEventArgs)
{
_mutex.WaitOne();
using (var sync = GWSSync.BuildSynchronizer(_log))
{
try
{
sync.Syncronize();
}
catch(Exception ex)
{
_log.Write(string.Format("Error during synchronization : {0}", ex));
}
}
_mutex.ReleaseMutex();
_syncTimer.Interval = TimeBeforeNextSync().TotalMilliseconds;
_syncTimer.Start();
}
There are a few methods like this in the file (i.e RunThis(), RunThat()). These methods run inside a Windows service and are called when a Timer elapses. Each of these methods are called using different Timers and set up like this:
//Synchro
var timeBeforeFirstSync = TimeBeforeNextSync();
_syncTimer = new System.Timers.Timer(timeBeforeFirstSync.TotalMilliseconds);
_syncTimer.AutoReset = false;
_syncTimer.Elapsed += RunSync;
_syncTimer.Start();
I understand that when the Timer elapses, the RunSync method will run. But when it hits the WaitOne() line, the thread is blocked. But who is it waiting for? Which "other" thread will send the signal?
WaitHandle is an abstraction, as stated in the documentation:
Encapsulates operating system–specific objects that wait for exclusive access to shared resources.
You don't know which other threads are involved, but you do know which other code is involved by checking the usage of the handle (_mutex in your case). Every WaitHandle derived class inherits WaitOne, but what happens after successful wait and how it's get signalled is specific. For instance, in your example _mutex most probably is a Mutex class, so WaitOne acts like "wait until it's free and take ownership" while the ReleaseMutex acts like "release ownership and signal". With that in mind, it should be obvious what all these methods do - ensuring that while RunThis you cannot RunThat and vise versa.
I am trying to do the following :
I have a server that is supposed to get many messages from a queue and process them. Now what I want is to create a new thread for every message and those threads will handle the response to the queue, I just want my server (core thread) to be just listening to messages and creating threads, not caring of what happens to them.
How can I achieve this? I know I can use the Thread class to create a thread but then the application just keeps listening to the thread until if finishes.
Also I can create an async method and run it but what happens when it finishes? Also the method is supposed to be static if I want it to be async but in my current application that is not a solution since I use many non static variables into this method.
Any ideas would be appreciated.
Unless you have very specific reason, I'd recommend using Tasks instead of Threads.
Likely they'll run in background anyway, but they produce less CPU/memory overhead and (in my opinion) are easier to handle in case of exception,...
Task t = Task.Run(() => ProcessMessage(message));
Maybe take a look at this introduction
What do you mean with
I know I can use the Thread class to create a thread but then the application just keeps listening to the thread until if finishes.
Just spawn the thread and let it run:
{
Thread t = new Thread(Foo);
t.Start();
}
public void Foo()
{ }
This won't make the main thread listen to the child thread, it just spawn them and continue working on following instructions.
BTW there are tons of result on how to create and run threads.
Since I don't like when others do it, here are simple examples of each way (asynchrnous/task-based), and you pick which one you like.
Asynchronous Implementation
int main()
{
while(true)
{
string data = SomeMethodThatReturnsTheNextDataFromQueue();
ProcessDataAsync(data);
}
}
async private void ProcessDataAsync(string msg)
{
// The *await* keyword returns to caller and allows main thread to continue looping.
bool result = await ParseDataAndSaveSomewhere(msg);
return;
}
Task-Based Implementation
int main()
{
while(true)
{
string data = SomeMethodThatReturnsTheNextDataFromQueue();
Task task = new Task(() => { ProcessData(data) });
task.Start();
}
}
private void ProcessData(string data)
{
// Do work
}
I've inherited a multi-threaded Windows Service (C#, .NET) with no support for unhanded exceptions. The service is using multiple threads to collect data from telemetry devices for analysis. A thread in this service could run for 24 hours or more. I'm struggling with how to tell the main thread that a thread is experiencing problems and needs to recycle. Here's a simplified view of the code:
class Program
{
static void Main(string[] args)
{
var workerObject = new WorkerObject();
var workerThread = new Thread(workerObject.DoWork);
workerThread.Start()
}
}
class WorkerObject
{
//todo: My fields and properties go here
public void DoWork()
{
const int timeout = 100;
//todo: setup wait handles here
try
{
//Start monitoring channels for this device
while (true)
{
// Wait on any waithandle or timeout once per decisecond.
int channelIndex = WaitHandle.WaitAny(waitHandles, timeout, false);
//todo: process incoming data for this channel
}
}
//Catch all exceptions so we can notify mommy that we're in a bad way
catch (Exception ex)
{
//todo: log anything that can help us figure this problem out
//How do I tell the main thread I've failed
}
finally
{
//But of course we want to clean up after ourselves
}
}
}
Is this even the best .NET threading mechanism to use? Should I be using Async Delegates or Task Parallel Library instead?
I had a similar requirement recently. I don't think that you can rely on the child threads telling the parent when they are bad. What if they are caught in an infinite loop or deadlocked for some reason? I settled in on a 'watch dog' approach. Each of the child thread needed to send a 'heartbeat' back to the main thread. If this signal was not received, then the thread was assumed 'dead' and an action could be taken. Here is a post about the architecture I settled in on:
http://blog.bobcravens.com/2009/08/monitored-watchdog-asynchronous-process-in-c/
Hope this helps.
Bob
Daniel Moth has blogged a lot about multithreading and more recently the Parallel Tasks support in .net 4.0. It's a great resource, http://www.danielmoth.com and very interesting. I'd definitely check that out.
I'm not sure if this helps but I worked on a "Report Runner" Windows Service which takes jobs from a queue and then schedules the work on the ThreadPool; this worked well because if a "Report" fails, I just log the error and exit the function and since it was scheduled in the ThreadPool it just gets returned to the pool to run more reports. Using the ThreadPool avoids the code needed to manage spinning up a new thread if the code you're running fails.
I have a class (NamedPipeManager) which has a thread (PipeThread) that waits for a NamedPipe connection using (ConnectNamedPipe) and then reads (ReadFile) - these are blocking calls (not-overlapped) - however there comes a point when I want to unblock them - for example when the calling class tries to stop the NamedPipeManager...
How can I interupt it? Using Thread.abort? Thread.interrupt? Is there a proper way to handle this?
Refer to the code below which illustrates my current situation
main()
{
NamedPipeManager np = new NamedPipeManager();
... do stuff ...
... do stuff ...
np.Stop(); // at this point I want to stop waiting on a connection
}
class NamedPipeManager
{
private Thread PipeThread;
public NamedPipeManager
{
PipeThread = new Thread(new ThreadStart(ManagePipes));
PipeThread.IsBackground = true;
PipeThread.Name = "NamedPipe Manager";
PipeThread.Start();
}
private void ManagePipes()
{
handle = CreateNamedPipe(..., PIPE_WAIT, ...);
ConnectNamedPipe(handle, null); // this is the BLOCKING call waiting for client connection
ReadFile(....); // this is the BLOCKING call to readfile after a connection has been established
}
public void Stop()
{
/// This is where I need to do my magic
/// But somehow I need to stop PipeThread
PipeThread.abort(); //?? my gut tells me this is bad
}
};
So, in function Stop() - how would I gracefully unblock the call to ConnectNamedPipe(...) or ReadFile(...)?
Any help would be appreciated.
Thanks,
It seems to be working on VC6.0, WinXP if I try to interrupt ConnectNamedPipe by
DeleteFile("\\\\.\\pipe\\yourpipehere");
So just specify name, not handle.
Starting with Windows Vista, there is a CancelSynchronousIO operation available for threads. I don't think there is a C# wrapper for it, so you would need to use PInvoke to call it.
Before Vista, there isn't really a way to perform such an operation gracefully. I would advise against using thread cancellation (which might work, but doesn't qualify as graceful). Your best approach is to use overlapped IO.
Recently I was in a situation, I could not use the Async Overlapped IO. I was stuck on the server side within ConnectNamedPipe. To unlock the thread and free resources, I had to connect to the same pipe as a client for a split second.
Main thread receives the stop signal
Main thread sets the stop event for the listening thread
Main thread connects to the pipe
If succeeded (always) - closes the newly created handle immediately
Listener thread unlocks
Listener thread does whatever required
This worked for me very well.
To unblock ReadFile one needs to connect and write to the pipe. Same effect epected.