【发布时间】:2021-07-14 12:49:21
【问题描述】:
这是一个调用“旧库”的代码演示,如果成功,则不返回任何内容,如果错误,则抛出异常。
public void ExampleCallOldCode()
{
List<string> users = new List<string>() {"user123", "user456"};
foreach (string userId in users)
{
try
{
Console.WriteLine($"Processing {userId} started");
DoSomethingSynchronously(userId);
Console.WriteLine($"Processing {userId} completed");
}
catch (Exception e)
{
Console.WriteLine($"Processing {userId} FAILED. {e.Message}");
}
}
}
public void DoSomethingSynchronously(string userId)
{
if (userId.Contains("123"))
Console.WriteLine($"Doing something with {userId}");
else
throw new Exception("UserId needs to contain 123.");
}
我们现在正在升级/集成到一个“新库”,它异步执行工作(在后台使用批处理/排队逻辑)并使用回调来通知成功或失败。
仅供参考:“旧库”是发送电子邮件的包装器。新库是Segment's Analytics.Net package
我不想更改太多旧代码(它在很多地方都使用过)。
- 如何同步等待新库完成并调用回调函数?
- 例如我应该使用
AutoResetEvents并致电WaitOne吗? - 还是有更好的选择?
- 例如我应该使用
- 如何处理错误?
- 是否要创建一个包装器并在失败回调函数中抛出异常?
public void ExampleNewCode()
{
// Segment initialization and payload setup
string writeKey = "PqRStUv1WxYzraGHijkA1Pz0AbcDE12F";
Config configWithBatchingOff = new Config().SetAsync(false);
Segment.Analytics.Initialize(writeKey, configWithBatchingOff);
Context context = new Context() {{"appName", "MyApp"}};
Options optionsContext = new Options().SetContext(context);
Properties properties = new Properties() {{"my_first_prop", "foo bar"}};
// setup callback handlers
Analytics.Client.Failed += FailureHandler;
Analytics.Client.Succeeded += SuccessHandler;
Logger.Handlers += LogHandler;
// ****
// the old code structure I want to preserve. HOW DO I MAKE THIS WORK ???
// ****
List<string> users = new List<string>() { "user123", "user456" };
foreach (string userId in users)
{
try
{
Console.WriteLine($"Processing {userId} started");
Analytics.Client.Track(userId, "Test Fired", properties, optionsContext);
Console.WriteLine($"Processing {userId} completed");
}
catch (Exception e)
{
Console.WriteLine($"Processing {userId} FAILED. {e.Message}");
}
}
}
public void FailureHandler(BaseAction action, System.Exception e)
{
Console.WriteLine($"FailureHandler called for userid={action.UserId}");
}
public void SuccessHandler(BaseAction action)
{
Console.WriteLine($"SuccessHandler called for userid={action.UserId}");
}
【问题讨论】:
标签: c# asynchronous async-await callback synchronization