Skip to content

Commit fc590f5

Browse files
Merge pull request #474 from freosc/PullRequest
Avoid Blocking Calls in App and AutoUpdater
2 parents b525bf1 + 5522add commit fc590f5

File tree

6 files changed

+277
-25
lines changed

6 files changed

+277
-25
lines changed

ElectronNET.API/App.cs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,27 @@ internal set
407407
/// which will be preferred over name by Electron.
408408
/// </summary>
409409
public string Name
410+
{
411+
[Obsolete("Use the asynchronous version NameAsync instead")]
412+
get
413+
{
414+
return NameAsync.Result;
415+
}
416+
set
417+
{
418+
BridgeConnector.Socket.Emit("appSetName", value);
419+
}
420+
}
421+
422+
/// <summary>
423+
/// A <see cref="string"/> property that indicates the current application's name, which is the name in the
424+
/// application's package.json file.
425+
///
426+
/// Usually the name field of package.json is a short lowercase name, according to the npm modules spec. You
427+
/// should usually also specify a productName field, which is your application's full capitalized name, and
428+
/// which will be preferred over name by Electron.
429+
/// </summary>
430+
public Task<string> NameAsync
410431
{
411432
get
412433
{
@@ -423,14 +444,11 @@ public string Name
423444
BridgeConnector.Socket.Emit("appGetName");
424445

425446
return taskCompletionSource.Task;
426-
}).Result;
427-
}
428-
set
429-
{
430-
BridgeConnector.Socket.Emit("appSetName", value);
447+
});
431448
}
432449
}
433450

451+
434452
internal App()
435453
{
436454
CommandLine = new CommandLine();
@@ -1479,6 +1497,27 @@ public void SetAboutPanelOptions(AboutPanelOptions options)
14791497
/// is used.
14801498
/// </summary>
14811499
public string UserAgentFallback
1500+
{
1501+
[Obsolete("Use the asynchronous version UserAgentFallbackAsync instead")]
1502+
get
1503+
{
1504+
return UserAgentFallbackAsync.Result;
1505+
}
1506+
set
1507+
{
1508+
BridgeConnector.Socket.Emit("appSetUserAgentFallback", value);
1509+
}
1510+
}
1511+
1512+
/// <summary>
1513+
/// A <see cref="string"/> which is the user agent string Electron will use as a global fallback.
1514+
/// <para/>
1515+
/// This is the user agent that will be used when no user agent is set at the webContents or
1516+
/// session level. It is useful for ensuring that your entire app has the same user agent. Set to a
1517+
/// custom value as early as possible in your app's initialization to ensure that your overridden value
1518+
/// is used.
1519+
/// </summary>
1520+
public Task<string> UserAgentFallbackAsync
14821521
{
14831522
get
14841523
{
@@ -1495,11 +1534,7 @@ public string UserAgentFallback
14951534
BridgeConnector.Socket.Emit("appGetUserAgentFallback");
14961535

14971536
return taskCompletionSource.Task;
1498-
}).Result;
1499-
}
1500-
set
1501-
{
1502-
BridgeConnector.Socket.Emit("appSetUserAgentFallback", value);
1537+
});
15031538
}
15041539
}
15051540

ElectronNET.API/AutoUpdater.cs

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
using ElectronNET.API.Entities;
2+
using Newtonsoft.Json;
23
using Newtonsoft.Json.Linq;
4+
using Newtonsoft.Json.Serialization;
35
using System;
6+
using System.Collections.Generic;
47
using System.Threading.Tasks;
58

69
namespace ElectronNET.API
@@ -182,11 +185,48 @@ public string UpdateConfigPath
182185
}
183186
}
184187

188+
/// <summary>
189+
/// The current application version
190+
/// </summary>
191+
public Task<SemVer> CurrentVersionAsync
192+
{
193+
get
194+
{
195+
return Task.Run<SemVer>(() =>
196+
{
197+
var taskCompletionSource = new TaskCompletionSource<SemVer>();
198+
199+
BridgeConnector.Socket.On("autoUpdater-currentVersion-get-reply", (result) =>
200+
{
201+
BridgeConnector.Socket.Off("autoUpdater-currentVersion-get-reply");
202+
SemVer version = ((JObject)result).ToObject<SemVer>();
203+
taskCompletionSource.SetResult(version);
204+
});
205+
BridgeConnector.Socket.Emit("autoUpdater-currentVersion-get");
206+
207+
return taskCompletionSource.Task;
208+
});
209+
}
210+
}
211+
185212
/// <summary>
186213
/// Get the update channel. Not applicable for GitHub.
187214
/// Doesn’t return channel from the update configuration, only if was previously set.
188215
/// </summary>
216+
[Obsolete("Use the asynchronous version ChannelAsync instead")]
189217
public string Channel
218+
{
219+
get
220+
{
221+
return ChannelAsync.Result;
222+
}
223+
}
224+
225+
/// <summary>
226+
/// Get the update channel. Not applicable for GitHub.
227+
/// Doesn’t return channel from the update configuration, only if was previously set.
228+
/// </summary>
229+
public Task<string> ChannelAsync
190230
{
191231
get
192232
{
@@ -199,11 +239,45 @@ public string Channel
199239
BridgeConnector.Socket.Off("autoUpdater-channel-get-reply");
200240
taskCompletionSource.SetResult(result.ToString());
201241
});
202-
203242
BridgeConnector.Socket.Emit("autoUpdater-channel-get");
204243

205244
return taskCompletionSource.Task;
206-
}).Result;
245+
});
246+
}
247+
}
248+
249+
250+
251+
/// <summary>
252+
/// The request headers.
253+
/// </summary>
254+
public Task<Dictionary<string, string>> RequestHeadersAsync
255+
{
256+
get
257+
{
258+
return Task.Run(() =>
259+
{
260+
var taskCompletionSource = new TaskCompletionSource<Dictionary<string, string>>();
261+
BridgeConnector.Socket.On("autoUpdater-requestHeaders-get-reply", (headers) =>
262+
{
263+
BridgeConnector.Socket.Off("autoUpdater-requestHeaders-get-reply");
264+
Dictionary<string, string> result = ((JObject)headers).ToObject<Dictionary<string, string>>();
265+
taskCompletionSource.SetResult(result);
266+
});
267+
BridgeConnector.Socket.Emit("autoUpdater-requestHeaders-get");
268+
return taskCompletionSource.Task;
269+
});
270+
}
271+
}
272+
273+
/// <summary>
274+
/// The request headers.
275+
/// </summary>
276+
public Dictionary<string, string> RequestHeaders
277+
{
278+
set
279+
{
280+
BridgeConnector.Socket.Emit("autoUpdater-requestHeaders-set", JObject.FromObject(value, _jsonSerializer));
207281
}
208282
}
209283

@@ -416,9 +490,26 @@ public Task<UpdateCheckResult> CheckForUpdatesAsync()
416490
string guid = Guid.NewGuid().ToString();
417491

418492
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesComplete" + guid, (updateCheckResult) =>
493+
{
494+
try
495+
{
496+
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesComplete" + guid);
497+
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesError" + guid);
498+
taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject<UpdateCheckResult>());
499+
}
500+
catch (Exception ex)
501+
{
502+
taskCompletionSource.SetException(ex);
503+
}
504+
});
505+
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesError" + guid, (error) =>
419506
{
420507
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesComplete" + guid);
421-
taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject<UpdateCheckResult>());
508+
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesError" + guid);
509+
string message = "An error occurred in CheckForUpdatesAsync";
510+
if (error != null && !string.IsNullOrEmpty(error.ToString()))
511+
message = JsonConvert.SerializeObject(error);
512+
taskCompletionSource.SetException(new Exception(message));
422513
});
423514

424515
BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdates", guid);
@@ -438,9 +529,29 @@ public Task<UpdateCheckResult> CheckForUpdatesAndNotifyAsync()
438529
string guid = Guid.NewGuid().ToString();
439530

440531
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid, (updateCheckResult) =>
532+
{
533+
try
534+
{
535+
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid);
536+
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyError" + guid);
537+
if (updateCheckResult == null)
538+
taskCompletionSource.SetResult(null);
539+
else
540+
taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject<UpdateCheckResult>());
541+
}
542+
catch (Exception ex)
543+
{
544+
taskCompletionSource.SetException(ex);
545+
}
546+
});
547+
BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesAndNotifyError" + guid, (error) =>
441548
{
442549
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid);
443-
taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject<UpdateCheckResult>());
550+
BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyError" + guid);
551+
string message = "An error occurred in autoUpdaterCheckForUpdatesAndNotify";
552+
if (error != null)
553+
message = JsonConvert.SerializeObject(error);
554+
taskCompletionSource.SetException(new Exception(message));
444555
});
445556

446557
BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdatesAndNotify", guid);
@@ -501,5 +612,10 @@ public Task<string> GetFeedURLAsync()
501612

502613
return taskCompletionSource.Task;
503614
}
615+
616+
private readonly JsonSerializer _jsonSerializer = new JsonSerializer()
617+
{
618+
ContractResolver = new CamelCasePropertyNamesContractResolver()
619+
};
504620
}
505621
}

ElectronNET.API/Entities/SemVer.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
namespace ElectronNET.API.Entities
2+
{
3+
/// <summary>
4+
///
5+
/// </summary>
6+
public class SemVer
7+
{
8+
/// <summary>
9+
///
10+
/// </summary>
11+
public string Raw { get; set; }
12+
/// <summary>
13+
///
14+
/// </summary>
15+
public bool Loose { get; set; }
16+
/// <summary>
17+
///
18+
/// </summary>
19+
public SemVerOptions Options { get; set; }
20+
/// <summary>
21+
///
22+
/// </summary>
23+
public int Major { get; set; }
24+
/// <summary>
25+
///
26+
/// </summary>
27+
public int Minor { get; set; }
28+
/// <summary>
29+
///
30+
/// </summary>
31+
public int Patch { get; set; }
32+
/// <summary>
33+
///
34+
/// </summary>
35+
public string Version { get; set; }
36+
/// <summary>
37+
///
38+
/// </summary>
39+
public string[] Build { get; set; }
40+
/// <summary>
41+
///
42+
/// </summary>
43+
public string[] Prerelease { get; set; }
44+
}
45+
46+
/// <summary>
47+
///
48+
/// </summary>
49+
public class SemVerOptions {
50+
/// <summary>
51+
///
52+
/// </summary>
53+
public bool? Loose { get; set; }
54+
/// <summary>
55+
///
56+
/// </summary>
57+
public bool? IncludePrerelease { get; set; }
58+
}
59+
}

ElectronNET.Host/api/autoUpdater.js

Lines changed: 19 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)