In C# (Net4.5, Win10) I wrote an email checker plugin. It handles Gmail/POP/IMAP. It works. But the plugin often freezes the app for a long time, if there's a connection problem etc. In C#, how can I "wrap" (delegate to a separate thread?) the GetEmails() function so that 1) it doesn't perceptibly "freeze" the rest of the app, 2) times out if it can't do its job within ~5 sec?
private static void GetEmails(int i) {
// if Gmail
cred = new NetworkCredential(user,password);
request = (HttpWebRequest)WebRequest.Create(atomURL);
try {
response = (HttpWebResponse)request.GetResponse();
...
// if POP
try {
pop.Connect();
...
// if IMAP
try {
imap.Connect();
...
}
CodePudding user response:
Your app freezes because all the operation is happening on main thread including UI. While long operation is in progress, main thread is busy doing stuff thus UI becomes unresponsive.
For this multi thread/parallel programming is done to delegate long operations on to a different thread.
There are multiple approaches to do multi threaded programming some are:
Task Parallel Library(TPL)
(recommended) or Background Worker
Task Parallel Library(TPL) visit link
Background Worker visit link
CodePudding user response:
If someone has the same issue. Most of the "async" docs promise to be simple, then balloon into bloat. Also, in an existing project, the "async/await" logic can get convoluted, require cascading changes, and you can get stuck on functions without GetAwaiter() (like GetResponse()). Here's a simple task wrapper I made for my existing function (with time-out).
Asynchronous programming in C-Sharp
var cts = new CancellationTokenSource();
var token = cts.Token;
cts.CancelAfter(5000);
Task task = Task.Run(() => { GetEmails(i, cts); }, token);
private static void GetEmails(int i, CancellationToken token) {
try {
...
token.ThrowIfCancellationRequested();
} catch (Exception ex) {
//will be thrown if cts.IsCancellationRequested
return;
}
}