Domanda

Non so quasi nulla di linq.

Sto facendo questo:

var apps = from app in Process.GetProcesses()
    where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
    select app;

Il che mi fornisce tutti i processi in esecuzione che corrispondono a tali criteri.

Ma non so come ottenere il primo.Gli esempi che posso trovare in rete sembrano implicare che devo farlo

var matchedApp = (from app in Process.GetProcesses()
    where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
    select app).First();

il che mi sembra un po' brutto e genera anche un'eccezione se non ci sono processi corrispondenti.C'è un modo migliore?

AGGIORNAMENTO

In realtà sto cercando di trovare il primo articolo corrispondente e chiamare SetForegroundWindow su di essa

Ho trovato questa soluzione, che mi sembra anche brutta e terribile, ma migliore della precedente.Qualche idea?

var unused = from app in Process.GetProcesses()
    where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
    select SetForegroundWindow( app.MainWindowHandle ); // side-effects in linq-query is technically bad I guess
È stato utile?

Soluzione

@FryHard FirstOrDefault funzionerà ma ricorda che restituisce null se non ne viene trovato nessuno.Questo codice non è testato ma dovrebbe essere vicino a quello che desideri:

var app = Process.GetProcesses().FirstOrDefault(p => p.ProcessName.Contains("MyAppName") && p.MainWindowHandle != IntPtr.Zero);

if (app == null)
    return;

SetForegroundWindow(app.MainWindowHandle);

Altri suggerimenti

Fare non utilizzo Count() come dice l'ICR. Count() ripeterà il file IEnumerable per capire quanti elementi ha.In questo caso la penalità in termini di prestazioni potrebbe essere trascurabile poiché non ci sono molti processi, ma è una cattiva abitudine.Utilizzare solo Count() quando la tua query è interessata solo a numero di risultati Count non è quasi mai una buona idea.

Ci sono diversi problemi con la risposta di FryHard.Innanzitutto, a causa di esecuzione ritardata, finirai per eseguire la query LINQ due volte, una volta per ottenere il numero di risultati e una volta per ottenere il numero di risultati FirstOrDefault.In secondo luogo, non vi è alcun motivo per utilizzarlo FirstOrDefault dopo aver controllato il conteggio.Poiché può restituire null, non dovresti mai usarlo senza controllare null.O farlo apps.First().MainWindowHandle O:

var app = apps.FirstOrDefault();

if (app != null)
    SetForegroundWindow(app.MainWindowHandle);

Questo è il motivo per cui la soluzione migliore è quella di Mark, senza dubbio.È il modo più efficiente e stabile di utilizzare LINQ per ottenere ciò che desideri.

Supponendo che nel tuo primo esempio apps sia un IEnumerable, potresti utilizzare le proprietà .Count e .FirstOrDefault per ottenere il singolo elemento che desideri passare a SetForegroundWindow.

var apps = from app in Process.GetProcesses()
where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
select app;

if (apps.Count > 0)
{
    SetForegroundWindow(apps.FirstOrDefault().MainWindowHandle );
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top