0

「Asynch」アノテーションが存在する場合、別のスレッドで関数を実行できるこのコードがあります。追加したばかりの新しい関数の戻り値も処理する必要があることに気付いた日を除いて、すべてが正常に機能します。これにはハンドラーとメッセージパッシングを使用できますが、既に構築されたプロジェクト構造 (巨大で正常に動作する) のため、メッセージパッシングで動作するように既存の関数を変更することはできません。

コードは次のとおりです。

/**
 * Defining the Asynch interface
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface Asynch {}

/**
 * Implementation of the Asynch interface. Every method in our controllers
 * goes through this interceptor. If the Asynch annotation is present,
 * this implementation invokes a new Thread to execute the method. Simple!
 */
public class AsynchInterceptor implements MethodInterceptor {
  public Object invoke(final MethodInvocation invocation) throws Throwable {
    Method method = invocation.getMethod();
    Annotation[] declaredAnnotations = method.getDeclaredAnnotations(); 
    if(declaredAnnotations != null && declaredAnnotations.length > 0) {
      for (Annotation annotation : declaredAnnotations) {
        if(annotation instanceof Asynch) {
          //start the requested task in a new thread and immediately
          //return back control to the caller
          new Thread(invocation.getMethod().getName()) {
            public void execute() {
              invocation.proceed();
            }
          }.start();
          return null;
        }
      }
    }
    return invocation.proceed();
  }
}

さて、次のように変換するにはどうすればよいですか:

@Asynch
public MyClass getFeedback(int clientId){

}

MyClass mResult = getFeedback(12345);

「mResult」は戻り値で更新されますか?

事前にサンクス...

4

1 に答える 1

2

基本的にはできません。同期的に何かgetFeedbackを返す必要があります。返されたオブジェクトを後で更新できる場合もあれば、明らかに更新できない場合もありますが、のような不変のクラスは明らかな例です。後で変数の値を変更することはできません...結局のところ、それはおそらくローカル変数です。実際、結果が計算されるまでに、それが使用された方法が完了している可能性があります...偽の値を使用しています。String mResult

同期言語の上に注釈を追加するだけでは、完全な非同期を実現することはできません。理想的には、非同期操作は、Future<T>「後で結果が出る」というようなものを返す必要があります。その結果が何であるか、計算されたかどうか、例外があったかどうかなどを確認する方法も含まれます。 。この種のことは、まさにasync/awaitC#5で追加された理由です-AOPを使用しても、ライブラリレベルで透過的に実行することはできないためです。非同期コードを作成することは、注釈を介して同期コードに追加されるものだけでなく、非常に慎重な決定である必要があります。

于 2013-02-11T08:06:56.943 に答える