Vorrei chiedere come convertire un metodo in modo che possa restituire qualsiasi tipo a seconda di cosa accade all'interno di esso.
Quello che ho è l'inizio di un'applicazione che visiterà un certo numero di pagine web (e alla fine eseguirà alcune attività su ciascuna) prima di passare alla successiva.
Al momento ho questo:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
namespace WindowsFormsApplication12
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
webBrowser1.ScriptErrorsSuppressed = true;
label1.MaximumSize = new Size(100, 0);
label1.AutoSize = true;
}
private void go_Click(object sender, EventArgs e)
{
ProcessUrlsAsync(new[] { "http://google.com", "http://microsoft.com", "http://yahoo.com" }).Start();
}
private void Exit(object sender, EventArgs e)
{
Application.Exit();
}
private Task ProcessUrlsAsync(string[] urls)
{
return new Task(() =>
{
foreach (string url in urls)
{
TaskAwaiter<string> awaiter = ProcessUrlAsync(url);
string result = awaiter.GetResult();
label1.Invoke((MethodInvoker)(() => label1.Text = result));
}
});
}
private Task ProcessUrlsAsync(string url)
{
return new Task(() =>
{
TaskAwaiter<string> awaiter = ProcessUrlAsync(url);
string result = awaiter.GetResult();
MessageBox.Show(result);
});
}
private TaskAwaiter<string> LoadWebPage(string url)
{
TaskCompletionSource<string> taskCompletionSource = new TaskCompletionSource<string>();
var handler = new WebBrowserDocumentCompletedEventHandler((s, e) =>
{
if (e.Url.Equals(url))
{
taskCompletionSource.SetResult(e.Url.ToString());
}
else
{
taskCompletionSource.SetResult(e.Url + ": " + webBrowser1.Document.Title);
}
});
webBrowser1.DocumentCompleted += handler;
taskCompletionSource.Task.ContinueWith(s => { webBrowser1.DocumentCompleted -= handler; });
webBrowser1.Navigate(url);
return taskCompletionSource.Task.GetAwaiter();
}
}
}
Quello che mi piacerebbe fare è cambiare
private TaskAwaiter<string> LoadWebPage(string url)
metodo in modo che restituisca un TaskAwaiter < tipo generico & gt ;. La mia ragione è che se non riesce ad accedere o si verifica un errore durante l'elaborazione, allora posso restituire un booleano o una stringa o un int per indicare il successo (o meno) delle azioni eseguite.
Inizialmente pensavo di sovraccaricare il metodo fino a quando non mi sono reso conto che questo non avrebbe funzionato con tipi di ritorno diversi, doh !!
I riferimenti alle pagine web sono solo lì come test per essere sicuro di poter avere le basi per aprire una pagina web. Una volta ottenuto questo, questi verranno sostituiti con le pagine Web dei miei sistemi prima che possa iniziare l'elaborazione.
È possibile convertire questo metodo in questo modo?
Modifica Mi piace l'aspetto della soluzione di @Bjarke Søgaard, quindi sto provando a implementarlo.
Sfortunatamente sono un po 'fitto a quest'ora della notte e per la vita di me non riesco a capire come usare il metodo. Finora ho questo:
TaskAwaiter<WebResponse> awaiter = LoadWebPage(url);
private TaskAwaiter<WebResponse> LoadWebPage(string url)
{
TaskCompletionSource<WebResponse> taskCompletionSource = new TaskCompletionSource<WebResponse>();
var handler = new WebBrowserDocumentCompletedEventHandler((s, e) =>
{
//taskCompletionSource.SetResult(e.Url + ": " + webBrowser1.Document.Title);
taskCompletionSource.SetResult(<< Stuck Here >>);
});
webBrowser1.DocumentCompleted += handler;
taskCompletionSource.Task.ContinueWith(s => { webBrowser1.DocumentCompleted -= handler; });
webBrowser1.Navigate(url);
return taskCompletionSource.Task.GetAwaiter();
}
Come puoi vedere, non so come impostare il risultato. Qualsiasi aiuto sarebbe apprezzato con questo.
Grazie