gpt4 book ai didi

c# - 异步命令模式——异常处理

转载 作者:行者123 更新时间:2023-11-30 13:25:16 24 4
gpt4 key购买 nike

我正在为客户端/服务器应用程序中的“客户端”类实现一个异步命令模式。我过去做过一些套接字编码,我喜欢他们在 Socket/SocketAsyncEventArgs 类中使用的新异步模式。

我的异步方法如下所示:public bool ExecuteAsync(Command cmd); 如果执行挂起则返回 true,如果同步完成则返回 false。 我的问题是:即使出现异常,我是否应该始终调用回调 (cmd.OnCompleted)?或者我应该直接从 ExecuteAsync 中抛出异常吗?

如果您需要,这里有更多详细信息。这类似于使用 SocketAsyncEventArgs,但我的类不是 SocketAsyncEventArgs,而是称为 SomeCmd。

SomeCmd cmd = new SomeCmd(23, 14, 10, "hike!");
cmd.OnCompleted += this.SomeCmd_OnCompleted;
this.ConnectionToServer.ExecuteAsync(cmd);

与 Socket 类一样,如果您需要与您的回调方法(在本例中为 SomeCmd_OnCompleted)协调,您可以使用 ExecuteAsync 的返回值来了解操作是否挂起 (true) 或操作是否同步完成。

SomeCmd cmd = new SomeCmd(23, 14, 10, "hike!");
cmd.OnCompleted += this.SomeCmd_OnCompleted;
if( this.ConnectionToServer.ExecuteAsync(cmd) )
{
Monitor.Wait( this.WillBePulsedBy_SomeCmd_OnCompleted );
}

这是我的基类的一个大大简化的版本,但您可以看到它是如何工作的:

class Connection
{
public bool ExecuteAsync(Command cmd)
{
/// CONSIDER: If you don't catch every exception here
/// then every caller of this method must have 2 sets of
/// exception handling:
/// One in the handler of Command.OnCompleted and one where ExecuteAsync
/// is called.
try
{
/// Some possible exceptions here:
/// 1) remote is disposed. happens when the other side disconnects (WCF).
/// 2) I do something wrong in TrackCommand (a bug that I want to fix!)
this.TrackCommand(cmd);
remote.ServerExecuteAsync( cmd.GetRequest() );
return true;
}
catch(Exception ex)
{
/// Command completing synchronously.
cmd.Completed(ex, true);
return false;
}
}
/// <summary>This is what gets called by some magic when the server returns a response.</summary>
internal CommandExecuteReturn(CommandResponse response)
{
Command cmd = this.GetTrackedCommand(response.RequestId);
/// Command completing asynchronously.
cmd.Completed(response, false);
}

private IServer remote;
}

abstract class Command: EventArgs
{
internal void Completed(Exception ex, bool synchronously)
{
this.Exception = ex;

this.CompletedSynchronously = synchronously;

if( this.OnCompleted != null )
{
this.OnCompleted(this);
}
}

internal void Completed(CommandResponse response, bool synchronously)
{
this.Response = response;
this.Completed(response.ExceptionFromServer, synchronously)
}

public bool CompletedSynchronously{ get; private set; }

public event EventHandler<Command> OnCompleted;

public Exception Exception{ get; private set; }

internal protected abstract CommandRequest GetRequest();
}

最佳答案

.NET 中异步操作的一个通用模式(至少对于 BackgroundWorkerBeginInvoke()/EndInvoke() 方法对来说是有一个结果对象将回调与实际返回值或发生的任何异常分开。回调负责处理异常。

一些类似 C# 的伪代码:


private delegate int CommandDelegate(string number);

private void ExecuteCommandAsync()
{
CommandDelegate del = new CommandDelegate(BeginExecuteCommand);
del.BeginInvoke("four", new AsyncCallback(EndExecuteCommand), null);
}

private int BeginExecuteCommand(string number)
{
if (number == "five")
{
return 5;
}
else
{
throw new InvalidOperationException("I only understand the number five!");
}
}

private void EndExecuteCommand(IAsyncResult result)
{
CommandDelegate del;
int retVal;

del = (CommandDelegate)((AsyncResult)result).AsyncDelegate;

try
{
// Here's where we get the return value
retVal = del.EndInvoke(result);
}
catch (InvalidOperationException e)
{
// See, we had EndExecuteCommand called, but the exception
// from the Begin method got tossed here
}
}

因此,如果您调用 ExecuteCommandAsync(),它会立即返回。 BeginExecuteCommand() 在单独的线程中启动。如果它抛出异常,则在您调用 IAsyncResult 上的 EndInvoke() 之前不会抛出该异常(您可以将其转换为 AsyncResult ,它已记录在案,但如果强制转换让您感到不舒服,您可以在 state 中传递它。这样,异常处理代码“自然地放置”在您将与方法的返回值交互的位置周围。

有关更多信息,请查看有关 the IAsyncResult pattern on MSDN 的更多信息.

希望这对您有所帮助。

关于c# - 异步命令模式——异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/297678/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com