.net 使用RX进行异常重试
我正在尝试一种有趣的模式,使用RX扩展进行异常重试。我有以下代码.net 使用RX进行异常重试,.net,winforms,exception-handling,system.reactive,.net,Winforms,Exception Handling,System.reactive,我正在尝试一种有趣的模式,使用RX扩展进行异常重试。我有以下代码 Public Async Function InitializeCommunications() As Task Await Observable.Create(Of Unit)(Async Function(observer) MessageBox.Show("Please press reset")
Public Async Function InitializeCommunications() As Task
Await Observable.Create(Of Unit)(Async Function(observer)
MessageBox.Show("Please press reset")
Await Me.Cockpit.LoadDriverToPLC()
MessageBox.Show("Please press start")
observer.OnNext(Unit.Default)
End Function).Retry()
End Function
该代码几乎完美地工作。如果LoadDriverToPLC中引发异常
然后,序列被重新订阅,正文重新运行,并要求用户
再次按“重置”
这段代码只有一个问题。第一次通过MessageBox调用
是正确的模态。这意味着他们坐在主窗口上方,你无法隐藏他们
不小心点击了主窗口。但是,如果引发异常并且
如果重试body,则MessageBox调用不再是模态调用
我确信这与RX计划有关。确保身体健康的诀窍是什么
总是在相同的上下文中运行吗
我打算稍后将这个模式包装起来,当我可以将它可靠地转换为
Public Async Function InitializeCommunications() As Task
Await RetryOn(of Exception)(Async Sub()
MessageBox.Show("Please press reset")
Await Me.Cockpit.LoadDriverToPLC()
MessageBox.Show("Please press start")
End Sub)
End Function
解决方案似乎是捕获同步上下文和 强制观察者在正确的上下文中得到通知,以便 使用相同的上下文重试
Public Async Function InitializeCommunications(msgFeedback As Func(Of String, Task)) As Task
Dim context = SynchronizationContext.Current
Await Observable.Create(Of Unit)(
Async Function(observer)
MessageBox.Show("Please press reset")
Await Me.Cockpit.LoadMessageLoopToPLC(111)
MessageBox.Show("Please press start")
observer.OnNext(Unit.Default)
End Function).ObserveOn(context).Retry()
End Function
另一种可能更好的方法是在对象上创建一些扩展方法,如下所示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FunctionalExtensions
{
public static class ObjectMixins
{
public static T Retry<Ex, T>(this Object This, int count, Func<T> action)
where Ex : Exception
{
while (true)
{
try
{
return action();
}
catch(Ex)
{
if (count==0)
{
throw;
}
count--;
}
}
}
public static async Task<T> Retry<Ex, T>(this Object This, int count, Func<Task<T>> action)
where Ex : Exception
{
while (true)
{
try
{
return await action();
}
catch(Ex)
{
if (count==0)
{
throw;
}
count--;
}
}
}
public static void Retry<Ex>(this Object This, int count, Action action)
where Ex : Exception
{
This.Retry<Ex, bool>(count, () => { action(); return true; });
}
public static async Task Retry<Ex>(this Object This, int count, Func<Task> action)
where Ex : Exception
{
await This.Retry<Ex, bool>(count, async () => { await action(); return true; });
}
public static void Retry<Ex>(this Object This, Action action)
where Ex : Exception
{
This.Retry<Ex, bool>(() => { action(); return true; });
}
public static T Retry<Ex, T>(this Object This, Func<T> action)
where Ex : Exception
{
while (true)
{
try
{
return action();
}
catch(Ex)
{
}
}
}
}
}
解决方案似乎是捕获同步上下文和 强制观察者在正确的上下文中得到通知,以便 使用相同的上下文重试
Public Async Function InitializeCommunications(msgFeedback As Func(Of String, Task)) As Task
Dim context = SynchronizationContext.Current
Await Observable.Create(Of Unit)(
Async Function(observer)
MessageBox.Show("Please press reset")
Await Me.Cockpit.LoadMessageLoopToPLC(111)
MessageBox.Show("Please press start")
observer.OnNext(Unit.Default)
End Function).ObserveOn(context).Retry()
End Function
另一种可能更好的方法是在对象上创建一些扩展方法,如下所示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FunctionalExtensions
{
public static class ObjectMixins
{
public static T Retry<Ex, T>(this Object This, int count, Func<T> action)
where Ex : Exception
{
while (true)
{
try
{
return action();
}
catch(Ex)
{
if (count==0)
{
throw;
}
count--;
}
}
}
public static async Task<T> Retry<Ex, T>(this Object This, int count, Func<Task<T>> action)
where Ex : Exception
{
while (true)
{
try
{
return await action();
}
catch(Ex)
{
if (count==0)
{
throw;
}
count--;
}
}
}
public static void Retry<Ex>(this Object This, int count, Action action)
where Ex : Exception
{
This.Retry<Ex, bool>(count, () => { action(); return true; });
}
public static async Task Retry<Ex>(this Object This, int count, Func<Task> action)
where Ex : Exception
{
await This.Retry<Ex, bool>(count, async () => { await action(); return true; });
}
public static void Retry<Ex>(this Object This, Action action)
where Ex : Exception
{
This.Retry<Ex, bool>(() => { action(); return true; });
}
public static T Retry<Ex, T>(this Object This, Func<T> action)
where Ex : Exception
{
while (true)
{
try
{
return action();
}
catch(Ex)
{
}
}
}
}
}