Ich habe Zweifel bezüglich einiger Best Practices bezüglich der asynchronen Ereignisse. Genauer gesagt im Zusammenhang den async
Modifikator auf eine void-Methode zur Zuordnung (das löst ein EventHandler
)Async-Ereignis bei C# Best Practice Confusion
Meine App funktionieren sollte einige Tests auf dem Hintergrund zu tun, und wenn ich die Ausführung beenden, um meine Ergebnisse zu meinem Db hochladen.
Bevor ich die Frage stelle, habe ich einen Blick über here geworfen, aber ich habe immer noch das Gefühl, dass ich etwas falsch mache.
Von dem, was ich getestet habe es keinen ersichtlichen Grund (für meinen speziellen Fall) ist die async
Modifikator anwenden, wenn ich den Event-Handler nenne, weil die Angabe der async
Modifikator subscriber's
zugrunde liegenden Methoden werden es ‚Dial-back‘ wenn ich die erste await
wiederfinde die Programmausführung, bis die erwartete Aktion beendet ist, funktioniert perfekt wie ich wollte.
Meine Zweifel kam, als ich begann die Anwendung (1'st Ansatz), um den async
Modifikator auf ein void-Methode (die WorkerClass
), obwohl es der Event-Handler ist, bin ich es falsch gemacht?
Ich habe den folgenden Test durchgeführt: eine gespeicherte Prozedur hergestellt, das es ist die Ausführung für etwa eine Minute verzögert
alter procedure TestStoredProcedure
@WhileValue int
as
begin
set nocount on;
begin transaction
begin try
waitfor delay '00:01';
insert into WhileResults(Value)
values
(@WhileValue)
commit tran;
end try
begin catch
raisError('Error',16,1);
rollback tran;
end catch;
return;
end
go
Das ist mein 1'st Ansatz ist:
class Program
{
static void Main(string[] args)
{
var workerClass = new WorkerClass();
var engine = new PlaybackEngine();
engine.TestFinishedEventHandler += workerClass.WorkSomething;
engine.TestRun();
}
}
class PlaybackEngine
{
public EventHandler TestFinishedEventHandler;
public void TestRun()
{
var i = 0;
while (i < 10000)
{
Console.WriteLine(i);
i++;
OnTestFinishedEventHandler(i,new EventArgs());
}
}
protected virtual void OnTestFinishedEventHandler(object sender, EventArgs args)
{
TestFinishedEventHandler?.Invoke(sender,args);
}
}
class WorkerClass
{
public async void WorkSomething(object sender, EventArgs args)
{
await UploadToDbAsync((int)sender);
}
private async Task UploadToDbAsync(int i)
{
using (var sqlConn = new SqlConnection("Data Source=EDWARD;Initial Catalog=TestDb;Integrated Security=True"))
using (var sqlCommand = new SqlCommand())
{
sqlConn.Open();
sqlCommand.Connection = sqlConn;
sqlCommand.CommandTimeout = 1000000;
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.CommandText = "dbo.TestStoredProcedure";
sqlCommand.Parameters.AddWithValue("@WhileValue", i);
await sqlCommand.ExecuteNonQueryAsync();
sqlConn.Close();
}
}
}
Mein zweiter Ansatz ist:
class Program
{
static void Main(string[] args)
{
var workerClass = new WorkerClass();
var engine = new PlaybackEngine();
// engine.TestFinishedEventHandler += workerClass.WorkSomething;
engine.TestFinished += workerClass.WorkSomething;
engine.TestRun();
}
}
class PlaybackEngine
{
public delegate Task TestRunEventHandler(object source, EventArgs args);
public event TestRunEventHandler TestFinished;
public void TestRun()
{
var i = 0;
while (i < 10000)
{
/* Doing some work here */
i++;
OnTestRan(i,new EventArgs());
Console.WriteLine(i);
}
}
protected virtual async void OnTestRan(object source, EventArgs args)
{
//await TestFinished?.Invoke(source, EventArgs.Empty);
if (TestFinished != null)
await TestFinished(source, new EventArgs());
}
}
class WorkerClass
{
public async Task WorkSomething(object sender, EventArgs args)
{
await UploadToDbAsync((int)sender);
}
private async Task UploadToDbAsync(int i)
{
using (var sqlConn = new SqlConnection("Data Source=EDWARD;Initial Catalog=TestDb;Integrated Security=True"))
using (var sqlCommand = new SqlCommand())
{
sqlConn.Open();
sqlCommand.Connection = sqlConn;
sqlCommand.CommandTimeout = 1000000;
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.CommandText = "dbo.TestStoredProcedure";
sqlCommand.Parameters.AddWithValue("@WhileValue", i);
await sqlCommand.ExecuteNonQueryAsync();
sqlConn.Close();
}
}