未验证 提交 14db256c 编写于 作者: H Heejae Chang 提交者: GitHub

Merge pull request #37943 from heejaechang/updateStatus

changed our task center status bar to say "low priority background pr…
......@@ -26,19 +26,26 @@ internal interface ISolutionCrawlerProgressReporter
internal struct ProgressData
{
public ProgressStatus Status { get; }
public string FilePathOpt { get; }
public ProgressData(ProgressStatus type, string filePathOpt)
/// <summary>
/// number of pending work item in the queue.
/// null means N/A for the associated <see cref="Status"/>
/// </summary>
public int? PendingItemCount { get; }
public ProgressData(ProgressStatus type, int? pendingItemCount)
{
Status = type;
FilePathOpt = filePathOpt;
PendingItemCount = pendingItemCount;
}
}
internal enum ProgressStatus
{
Started,
Updated,
Paused,
PendingItemCountUpdated,
Evaluating,
Stoped
}
}
......@@ -2,9 +2,6 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.SolutionCrawler
{
......@@ -13,115 +10,89 @@ internal partial class SolutionCrawlerRegistrationService : ISolutionCrawlerRegi
/// <summary>
/// Progress reporter
///
/// initial implementation doesn't care about each specific item's progress.
/// but as a whole whether there is anything going on. later if there is any need to track each item's progress specifically such as
/// higher/normal/lower queue, then we can change this to track those separately.
/// this progress reporter is a best effort implementation. it doesn't stop world to find out accurate data
///
/// what this reporter care is we show start/stop background work and show things are moving or paused
/// without too much cost.
///
/// due to how solution cralwer calls Start/Stop (see caller of those 2), those 2 can't have a race
/// and that is all we care for this reporter
/// </summary>
private class SolutionCrawlerProgressReporter : ISolutionCrawlerProgressReporter
{
private readonly IAsynchronousOperationListener _listener;
// we use ref count here since solution crawler has multiple queues per priority
// where an item can be enqueued and dequeued independently.
// first item added in any of those queues will cause the "start" event to be sent
// and the very last item processed from those queues will cause "stop" event to be sent
// evaluating and paused is also ref counted since work in the lower priority queue can
// be canceled due to new higher priority work item enqueued to higher queue.
// but before lower priority work actually exit due to cancellation, higher work could
// start processing. causing an overlap. the ref count make sure that exiting lower
// work doesn't flip evaluating state to paused state.
private int _progressStartCount = 0;
private int _progressEvaluateCount = 0;
// use event map and event queue so that we can guarantee snapshot and sequential ordering of events from
// multiple consumer from possibly multiple threads
private readonly SimpleTaskQueue _eventQueue;
private readonly EventMap _eventMap;
public event EventHandler<ProgressData> ProgressChanged;
// this is to reduce number of times we report progress on same file. this is purely for perf
private string _lastReportedFilePath;
public bool InProgress => _progressStartCount > 0;
private int _count;
public void Start() => ChangeProgressStatus(ref _progressStartCount, ProgressStatus.Started);
public void Stop() => ChangeProgressStatus(ref _progressStartCount, ProgressStatus.Stoped);
public SolutionCrawlerProgressReporter(IAsynchronousOperationListener listener)
{
_listener = listener;
_eventQueue = new SimpleTaskQueue(TaskScheduler.Default);
_eventMap = new EventMap();
private void Evaluate() => ChangeProgressStatus(ref _progressEvaluateCount, ProgressStatus.Evaluating);
private void Pause() => ChangeProgressStatus(ref _progressEvaluateCount, ProgressStatus.Paused);
_count = 0;
}
public bool InProgress
public void UpdatePendingItemCount(int pendingItemCount)
{
get
if (_progressStartCount > 0)
{
return _count > 0;
var progressData = new ProgressData(ProgressStatus.PendingItemCountUpdated, pendingItemCount);
OnProgressChanged(progressData);
}
}
public event EventHandler<ProgressData> ProgressChanged
/// <summary>
/// Allows the solution crawler to start evaluating work enqueued to it.
/// Returns an IDisposable that the caller must dispose of to indicate that it no longer needs the crawler to continue evaluating.
/// Multiple callers can call into this simultaneously.
/// Only when the last one actually disposes the scope-object will the crawler
/// actually revert back to the paused state where no work proceeds.
/// </summary>
public IDisposable GetEvaluatingScope()
{
add
{
_eventMap.AddEventHandler(nameof(ProgressChanged), value);
}
remove
{
_eventMap.RemoveEventHandler(nameof(ProgressChanged), value);
}
return new ProgressStatusRAII(this);
}
public Task Start()
private void ChangeProgressStatus(ref int referenceCount, ProgressStatus status)
{
if (Interlocked.Increment(ref _count) == 1)
var start = status == ProgressStatus.Started || status == ProgressStatus.Evaluating;
if (start ? (Interlocked.Increment(ref referenceCount) == 1) : (Interlocked.Decrement(ref referenceCount) == 0))
{
_lastReportedFilePath = null;
var asyncToken = _listener.BeginAsyncOperation("ProgressReportStart");
var progressData = new ProgressData(ProgressStatus.Started, filePathOpt: null);
return RaiseEvent(nameof(ProgressChanged), progressData).CompletesAsyncOperation(asyncToken);
var progressData = new ProgressData(status, pendingItemCount: null);
OnProgressChanged(progressData);
}
return Task.CompletedTask;
}
public Task Stop()
private void OnProgressChanged(ProgressData progressData)
{
if (Interlocked.Decrement(ref _count) == 0)
{
_lastReportedFilePath = null;
var asyncToken = _listener.BeginAsyncOperation("ProgressReportStop");
var progressData = new ProgressData(ProgressStatus.Stoped, filePathOpt: null);
return RaiseEvent(nameof(ProgressChanged), progressData).CompletesAsyncOperation(asyncToken);
}
return Task.CompletedTask;
ProgressChanged?.Invoke(this, progressData);
}
public Task Update(string filePath)
private struct ProgressStatusRAII : IDisposable
{
if (_count > 0)
{
if (_lastReportedFilePath == filePath)
{
// don't report same file multiple times
return Task.CompletedTask;
}
_lastReportedFilePath = filePath;
private readonly SolutionCrawlerProgressReporter _owner;
var asyncToken = _listener.BeginAsyncOperation("ProgressReportUpdate");
var progressData = new ProgressData(ProgressStatus.Updated, filePath);
return RaiseEvent(nameof(ProgressChanged), progressData).CompletesAsyncOperation(asyncToken);
public ProgressStatusRAII(SolutionCrawlerProgressReporter owner)
{
_owner = owner;
_owner.Evaluate();
}
return Task.CompletedTask;
}
private Task RaiseEvent(string eventName, ProgressData progressData)
{
// this method name doesn't have Async since it should work as async void.
var ev = _eventMap.GetEventHandlers<EventHandler<ProgressData>>(eventName);
if (ev.HasHandlers)
public void Dispose()
{
return _eventQueue.ScheduleTask(() =>
{
ev.RaiseEvent(handler => handler(this, progressData));
});
_owner.Pause();
}
return Task.CompletedTask;
}
}
......
......@@ -40,7 +40,7 @@ internal partial class SolutionCrawlerRegistrationService : ISolutionCrawlerRegi
_documentWorkCoordinatorMap = new Dictionary<Workspace, WorkCoordinator>(ReferenceEqualityComparer.Instance);
_listener = listenerProvider.GetListener(FeatureAttribute.SolutionCrawler);
_progressReporter = new SolutionCrawlerProgressReporter(_listener);
_progressReporter = new SolutionCrawlerProgressReporter();
}
public void Register(Workspace workspace)
......
......@@ -47,13 +47,24 @@ public AsyncWorkItemQueue(SolutionCrawlerProgressReporter progressReporter, Work
protected abstract bool TryTakeAnyWork_NoLock(ProjectId preferableProjectId, ProjectDependencyGraph dependencyGraph, IDiagnosticAnalyzerService service, out WorkItem workItem);
public int WorkItemCount
{
get
{
lock (_gate)
{
return WorkItemCount_NoLock;
}
}
}
public bool HasAnyWork
{
get
{
lock (_gate)
{
return HasAnyWork_NoLock;
return WorkItemCount_NoLock > 0;
}
}
}
......@@ -137,7 +148,6 @@ public void Dispose()
RaiseCancellation_NoLock(cancellations);
}
private bool HasAnyWork_NoLock => WorkItemCount_NoLock > 0;
protected Workspace Workspace => _workspace;
private static void RaiseCancellation_NoLock(List<CancellationTokenSource> cancellations)
......
......@@ -46,6 +46,7 @@ private sealed class HighPriorityProcessor : IdleProcessor
public Task Running => _running;
public int WorkItemCount => _workItemQueue.WorkItemCount;
public bool HasAnyWork => _workItemQueue.HasAnyWork;
public void AddAnalyzer(IIncrementalAnalyzer analyzer)
......
......@@ -103,6 +103,8 @@ public void Enqueue(WorkItem item)
_highPriorityProcessor.Enqueue(item);
_normalPriorityProcessor.Enqueue(item);
_lowPriorityProcessor.Enqueue(item);
ReportPendingWorkItemCount();
}
public void AddAnalyzer(IIncrementalAnalyzer analyzer, bool highPriorityForActiveFile)
......@@ -155,6 +157,12 @@ private void ResetLogAggregator()
_logAggregator = new LogAggregator();
}
private void ReportPendingWorkItemCount()
{
var pendingItemCount = _highPriorityProcessor.WorkItemCount + _normalPriorityProcessor.WorkItemCount + _lowPriorityProcessor.WorkItemCount;
_registration.ProgressReporter.UpdatePendingItemCount(pendingItemCount);
}
private async Task ProcessDocumentAnalyzersAsync(
Document document, ImmutableArray<IIncrementalAnalyzer> analyzers, WorkItem workItem, CancellationToken cancellationToken)
{
......@@ -182,12 +190,9 @@ private void ResetLogAggregator()
Func<IIncrementalAnalyzer, T, CancellationToken, Task> runnerAsync,
CancellationToken cancellationToken)
{
// this is a best effort progress report. since we don't clear up
// reported progress when work is done or cancelled. it is possible
// that last reported work is left in report even if it is already processed.
// but when everything is finished, report should get cleared
_ = _registration.ProgressReporter.Update(GetFilePath(value));
using var evaluating = _registration.ProgressReporter.GetEvaluatingScope();
ReportPendingWorkItemCount();
foreach (var analyzer in analyzers)
{
if (cancellationToken.IsCancellationRequested)
......@@ -243,26 +248,6 @@ private async Task RunBodyAnalyzersAsync(ImmutableArray<IIncrementalAnalyzer> an
}
}
private static string GetFilePath(object value)
{
if (value is Document document)
{
return document.FilePath;
}
if (value is Project project)
{
return project.FilePath;
}
if (value is Solution solution)
{
return solution.FilePath;
}
throw ExceptionUtilities.UnexpectedValue(value);
}
private static async Task<TResult> GetOrDefaultAsync<TData, TResult>(TData value, Func<TData, CancellationToken, Task<TResult>> funcAsync, CancellationToken cancellationToken)
{
try
......
......@@ -37,6 +37,8 @@ private sealed class LowPriorityProcessor : AbstractPriorityProcessor
Start();
}
public int WorkItemCount => _workItemQueue.WorkItemCount;
protected override Task WaitAsync(CancellationToken cancellationToken)
{
return _workItemQueue.WaitAsync(cancellationToken);
......
......@@ -118,7 +118,7 @@ protected override Task WaitAsync(CancellationToken cancellationToken)
}
public Task Running => _running;
public int WorkItemCount => _workItemQueue.WorkItemCount;
public bool HasAnyWork => _workItemQueue.HasAnyWork;
protected override async Task ExecuteAsync()
......
......@@ -2,8 +2,11 @@
using System;
using System.ComponentModel.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.SolutionCrawler;
using Microsoft.VisualStudio.TaskStatusCenter;
using Roslyn.Utilities;
......@@ -22,6 +25,28 @@ internal sealed class TaskCenterSolutionAnalysisProgressReporter
private TaskCompletionSource<VoidResult> _currentTask;
private DateTimeOffset _lastTimeReported;
private int _lastPendingItemCount;
private ProgressStatus _lastProgressStatus;
private ProgressStatus _lastShownProgressStatus;
// _resettableDelay makes sure that we at the end update status to correct value.
// in contrast to _lastTimeReported makes sure that we only update at least s_minimumInterval interval.
//
// for example, when an event stream comes in as below (assuming 200ms minimum interval)
// e1 -> (100ms)-> e2 -> (300ms)-> e3 -> (100ms) -> e4
//
// actual status shown to users without _resettableDelay will be
// e1 -> e3.
//
// e2 and e4 will be skipped since interval was smaller than min interval.
// losing e2 is fine, but e4 is problematic since the user now could see the wrong status
// until the next event comes in.
// for example, it could show "Evaluating" when it is actually "Paused" until the next event
// which could be long time later.
// what _resettableDelay does is making sure that if the next event doesn't come in
// within certain delay, it updates status to e4 (current).
private ResettableDelay _resettableDelay;
// this is only field that is shared between 2 events streams (IDiagnosticService and ISolutionCrawlerProgressReporter)
// and can be called concurrently.
private volatile ITaskHandler _taskHandler;
......@@ -33,12 +58,15 @@ internal sealed class TaskCenterSolutionAnalysisProgressReporter
VisualStudioWorkspace workspace)
{
_lastTimeReported = DateTimeOffset.UtcNow;
_resettableDelay = null;
ResetProgressStatus();
_taskCenterService = (IVsTaskStatusCenterService)taskStatusCenterService;
_options = new TaskHandlerOptions()
{
Title = ServicesVSResources.Live_analysis,
Title = ServicesVSResources.Running_low_priority_background_processes,
ActionsAfterCompletion = CompletionActions.None
};
......@@ -60,36 +88,76 @@ private void OnSolutionCrawlerProgressChanged(object sender, ProgressData progre
case ProgressStatus.Started:
StartedOrStopped(started: true);
break;
case ProgressStatus.Updated:
ProgressUpdated(progressData.FilePathOpt);
case ProgressStatus.PendingItemCountUpdated:
_lastPendingItemCount = progressData.PendingItemCount.Value;
ProgressUpdated();
break;
case ProgressStatus.Stoped:
StartedOrStopped(started: false);
break;
case ProgressStatus.Evaluating:
case ProgressStatus.Paused:
_lastProgressStatus = progressData.Status;
ProgressUpdated();
break;
default:
throw ExceptionUtilities.UnexpectedValue(progressData.Status);
}
}
private void ProgressUpdated(string filePathOpt)
private void ProgressUpdated()
{
// we prefer showing evaluating if progress is flipping between evaluate and pause
// in short period of time.
var forceUpdate = _lastShownProgressStatus == ProgressStatus.Paused &&
_lastProgressStatus == ProgressStatus.Evaluating;
var current = DateTimeOffset.UtcNow;
if (current - _lastTimeReported < s_minimumInterval)
if (!forceUpdate && current - _lastTimeReported < s_minimumInterval)
{
// make sure we are not flooding UI.
// this is just presentation, fine to not updating UI especially since
// this is just presentation, fine to not updating UI right away especially since
// at the end, this notification will go away automatically
// but to make UI to be updated to right status eventually if task takes long time to finish
// we enqueue refresh task.
EnqueueRefresh();
return;
}
_lastShownProgressStatus = _lastProgressStatus;
_lastTimeReported = current;
ChangeProgress(_taskHandler, filePathOpt != null ? string.Format(ServicesVSResources.Analyzing_0, FileNameUtilities.GetFileName(filePathOpt)) : null);
ChangeProgress(_taskHandler, GetMessage());
string GetMessage()
{
var statusMessage = (_lastProgressStatus == ProgressStatus.Paused) ? ServicesVSResources.Paused_0_tasks_in_queue : ServicesVSResources.Evaluating_0_tasks_in_queue;
return string.Format(statusMessage, _lastPendingItemCount);
}
void EnqueueRefresh()
{
if (_resettableDelay != null)
{
_resettableDelay.Reset();
return;
}
_resettableDelay = new ResettableDelay((int)s_minimumInterval.TotalMilliseconds, AsynchronousOperationListenerProvider.NullListener);
_resettableDelay.Task.SafeContinueWith(_ =>
{
_resettableDelay = null;
ProgressUpdated();
}, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
}
}
private void StartedOrStopped(bool started)
{
if (started)
{
ResetProgressStatus();
// if there is any pending one. make sure it is finished.
_currentTask?.TrySetResult(default);
......@@ -114,9 +182,18 @@ private void StartedOrStopped(bool started)
_currentTask = null;
_taskHandler = null;
ResetProgressStatus();
}
}
private void ResetProgressStatus()
{
_lastPendingItemCount = 0;
_lastProgressStatus = ProgressStatus.Paused;
_lastShownProgressStatus = ProgressStatus.Paused;
}
private static void ChangeProgress(ITaskHandler taskHandler, string message)
{
var data = new TaskProgressData
......
......@@ -1015,6 +1015,15 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Evaluating ({0} tasks in queue).
/// </summary>
internal static string Evaluating_0_tasks_in_queue {
get {
return ResourceManager.GetString("Evaluating_0_tasks_in_queue", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Event type is invalid.
/// </summary>
......@@ -1470,15 +1479,6 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Live analysis.
/// </summary>
internal static string Live_analysis {
get {
return ResourceManager.GetString("Live_analysis", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Live analysis (VSIX extension).
/// </summary>
......@@ -2254,6 +2254,15 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Paused ({0} tasks in queue).
/// </summary>
internal static string Paused_0_tasks_in_queue {
get {
return ResourceManager.GetString("Paused_0_tasks_in_queue", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Pick members.
/// </summary>
......@@ -2818,6 +2827,15 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Running low priority background processes.
/// </summary>
internal static string Running_low_priority_background_processes {
get {
return ResourceManager.GetString("Running_low_priority_background_processes", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sample Identifier:.
/// </summary>
......
......@@ -1060,9 +1060,6 @@ I agree to all of the foregoing:</value>
<data name="Analyzing_0" xml:space="preserve">
<value>Analyzing '{0}'</value>
</data>
<data name="Live_analysis" xml:space="preserve">
<value>Live analysis</value>
</data>
<data name="Prefer_conditional_expression_over_if_with_assignments" xml:space="preserve">
<value>Prefer conditional expression over 'if' with assignments</value>
</data>
......@@ -1343,4 +1340,13 @@ I agree to all of the foregoing:</value>
<data name="Use_editorconfig_compatibility_mode" xml:space="preserve">
<value>Use .editorconfig compatibility mode (requires restart)</value>
</data>
<data name="Running_low_priority_background_processes" xml:space="preserve">
<value>Running low priority background processes</value>
</data>
<data name="Evaluating_0_tasks_in_queue" xml:space="preserve">
<value>Evaluating ({0} tasks in queue)</value>
</data>
<data name="Paused_0_tasks_in_queue" xml:space="preserve">
<value>Paused ({0} tasks in queue)</value>
</data>
</root>
\ No newline at end of file
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">Dokončit</target>
......@@ -127,11 +132,6 @@
<target state="translated">Druh</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">Předvolby závorek:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">Preferovat složená přiřazení</target>
......@@ -392,6 +397,11 @@
<target state="translated">Zkontrolovat změny</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">Uložit soubor .editorconfig</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">Beenden</target>
......@@ -127,11 +132,6 @@
<target state="translated">Art</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">Voreinstellungen für Klammern:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">Zusammengesetzte Zuweisungen bevorzugen</target>
......@@ -392,6 +397,11 @@
<target state="translated">Änderungen überprüfen</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">EDITORCONFIG-Datei speichern</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">Finalizar</target>
......@@ -127,11 +132,6 @@
<target state="translated">Tipo</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">Preferencias de paréntesis:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">Preferir asignaciones compuestas</target>
......@@ -392,6 +397,11 @@
<target state="translated">Revisar cambios</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">Guardar archivo .editorconfig</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">Terminer</target>
......@@ -127,11 +132,6 @@
<target state="translated">Genre</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">Préférences relatives aux parenthèses :</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">Préférer les affectations composées</target>
......@@ -392,6 +397,11 @@
<target state="translated">Passer en revue les changements</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">Enregistrer le fichier .editorconfig</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">Fine</target>
......@@ -127,11 +132,6 @@
<target state="translated">Tipo</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">Preferenze per parentesi:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">Preferisci assegnazioni composte</target>
......@@ -392,6 +397,11 @@
<target state="translated">Esamina modifiche</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">Salva file con estensione editorconfig</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">終了</target>
......@@ -127,11 +132,6 @@
<target state="translated">種類</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">かっこの優先順位:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">複合割り当てを優先</target>
......@@ -392,6 +397,11 @@
<target state="translated">変更のプレビュー</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">.editorconfig ファイルの保存</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">마침</target>
......@@ -127,11 +132,6 @@
<target state="translated">종류</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">괄호 기본 설정:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">복합 대입 선호</target>
......@@ -392,6 +397,11 @@
<target state="translated">변경 내용 검토</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">editorconfig 파일 저장</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">Zakończ</target>
......@@ -127,11 +132,6 @@
<target state="translated">Rodzaj</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">Preferencje dotyczące nawiasów:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">Preferuj przypisania złożone</target>
......@@ -392,6 +397,11 @@
<target state="translated">Przejrzyj zmiany</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">Zapisz plik .editorconfig</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">Concluir</target>
......@@ -127,11 +132,6 @@
<target state="translated">Tipo</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">Preferências de parênteses:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">Preferir atribuições de compostos</target>
......@@ -392,6 +397,11 @@
<target state="translated">Revisar alterações</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">Salvar arquivo .editorconfig</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">Готово</target>
......@@ -127,11 +132,6 @@
<target state="translated">Вид</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">Параметры круглых скобок:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">Предпочитать составные присваивания</target>
......@@ -392,6 +397,11 @@
<target state="translated">Проверить изменения</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">Сохранить файл EDITORCONFIG</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">Son</target>
......@@ -127,11 +132,6 @@
<target state="translated">Tür</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">Parantez tercihleri:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">Bileşik atamaları tercih et</target>
......@@ -392,6 +397,11 @@
<target state="translated">Değişiklikleri Gözden Geçir</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">.editorconfig dosyasını kaydet</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">完成</target>
......@@ -127,11 +132,6 @@
<target state="translated">种类</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">括号首选项:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">首选复合赋值</target>
......@@ -392,6 +397,11 @@
<target state="translated">预览更改</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">保存 .editorconfig 文件</target>
......
......@@ -87,6 +87,11 @@
<target state="new">Enable nullable reference analysis IDE features</target>
<note />
</trans-unit>
<trans-unit id="Evaluating_0_tasks_in_queue">
<source>Evaluating ({0} tasks in queue)</source>
<target state="new">Evaluating ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Finish">
<source>Finish</source>
<target state="translated">完成</target>
......@@ -127,11 +132,6 @@
<target state="translated">種類</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis">
<source>Live analysis</source>
<target state="new">Live analysis</target>
<note />
</trans-unit>
<trans-unit id="Live_analysis_VSIX_extension">
<source>Live analysis (VSIX extension)</source>
<target state="new">Live analysis (VSIX extension)</target>
......@@ -332,6 +332,11 @@
<target state="translated">括號喜好設定:</target>
<note />
</trans-unit>
<trans-unit id="Paused_0_tasks_in_queue">
<source>Paused ({0} tasks in queue)</source>
<target state="new">Paused ({0} tasks in queue)</target>
<note />
</trans-unit>
<trans-unit id="Prefer_compound_assignments">
<source>Prefer compound assignments</source>
<target state="translated">優先使用複合指派</target>
......@@ -392,6 +397,11 @@
<target state="translated">檢閱變更</target>
<note />
</trans-unit>
<trans-unit id="Running_low_priority_background_processes">
<source>Running low priority background processes</source>
<target state="new">Running low priority background processes</target>
<note />
</trans-unit>
<trans-unit id="Save_dot_editorconfig_file">
<source>Save .editorconfig file</source>
<target state="translated">儲存 .editorconfig 檔案</target>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册