我对于有关异步事件的一些最佳实践有一些疑问。更确切地涉及到分配async
修改为void方法(即触发EventHandler
)关于C#最佳实践混淆的异步事件
我的应用程序应该工作做的背景,当我完成了执行上传我的结果我的数据库一些测试。
在问这个问题之前,我看过here,但我仍然觉得我做错了什么。
从我测试过没有明显的原因(我的具体情况)申请时,我调用事件处理程序,因为指定async
修饰符subscriber's
基本方法,它会“回拨”的async
修改当遇到第一个await
恢复程序执行,直到等待的动作完成,按照我想要的完美工作。
当我开始向无效方法(WorkerClass
)应用(1'st方法)async
修改器时,我怀疑是否即使它是事件处理程序,我是否在做错误?
我已经做了以下测试: 取得了存储过程,而延缓它的运行了大约一分钟
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
这是我的第1'的做法:
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();
}
}
}
我的第二个方法是:
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();
}
}