2016-03-23 7 views
2

私はwebservicesの初心者ですが、 で実行しました。これはWebサービスと非同期ログに関する問題です。 (C#)C#Webservice:非同期メソッドを呼び出すWebmethodがTaskoffオブジェクトを返します

問題の説明

私は、クライアント(asp.netのウェブサイト)にいくつかのデータを返すWebサービスを持っています。

[WebMethod] 
public MyClass getData() 
{ 
    //Do some work 
    return _myClassObject; 
} 

これまでのところ、これはかなりうまくいきます。

Webサービスが公開されたら、何が起こっているのか知りたいので、簡単なロギングを実装しようとしました。

次のクラス(簡体字)がログを処理します。

public static class Logwriter 
{ 
    public static void writeToLog(string txt) 
    { 
     //writes log to db 
    } 
} 

私は、これは非同期に発生しますので、Webサービスを遅くはありません。

。したがって、私はWebMethod属性変更:私は私のasp.netのウェブサイトにServiceReferenceを更新した後

[WebMethod] 
public async Task<MyClass> getData() 
{ 
    await Task.Run(() => Logwriter.writeToLog("Someone requested the WebMethod 'GetData'")); 
    //Do some work 
    return _myClassObject; 
} 

を私はウェブサーバは、もはや「MyClassの」-objectを返すことに気づいていないが、「TaskOffCustomClass」-object 。私は "TaskOffMyClass"オブジェクトから "MyClass"オブジェクトを取得する解決策を見つけられませんでした。

質問私は "TaskOffMyClass" から私の "MyClassの" オブジェクトを取得できますか

  1. ロギングを非同期で行い、依然として "MyClass" -Objectを返す可能性はありますか? (タスクの使用中)

  2. 私はスレッドでロギングを行うことを考えましたが、Task over Threadを使用するにはrecommendedであることも読んでいます。スレッドへの切り替えの影響はどれくらいかかりますか?あなたが最初のバージョンで

    MyClass result = await service.getData(); 
    

    または

    Task<MyClass> task = service.getData(); 
    MyClass result = task.Result; 
    

    を使用することができますいずれか

+2

'async'と' await'は、あなたが思うように動作しません。上記のコードで行ったことは、その一部を別のスレッドで実行させることですが、元のスレッドが続行される前にそのスレッドが実行を終了するまで待ちます。私はあなたに 'async'と' await'について学ぶ時間を増やすことを強くお勧めします。 Eric Lippertのブログには、それを説明している数多くの記事がありました。 –

+0

こんにちは@Damien_The_Unbliever、ご意見ありがとうございます。私は間違いなくEric Lippertsのブログを見ていきます。 – Martin

答えて

0

私は私はあなたが現代的なフレームワークを学ぶお勧めしますWebサービス

との合計初心者です。私は何年ものASMXが今は知りません...私が見つけたことによると、それは "死んではいません"しかし、私はシルバーライトと同じ種類の "死んでいない"と思います。言い換えれば、それは死んでいますが、彼らは正式に死んだと言ってほしくはありません。

特に、私はASMXがasyncやタスクを全く理解していないと思います。 I 強くは、ASP.NET WebAPI(またはの場合は実際にがSOAPを望む場合はWCF)をお勧めします。 Crowcoder pointed outとして - - あなたは、その後、維持する必要がある既存のWebメソッド...

実現する最初のものを持っている場合

しかし、あなたはおそらく火が-と-忘れしたくないということです。それは十分に機能している場合、ちょうどこのようにそれを維持:

[WebMethod] 
public MyClass getData() 
{ 
    Logwriter.writeToLog("Someone requested the WebMethod 'GetData'"); 
    //Do some work 
    return _myClassObject; 
} 

あなたが認識し、彼らがいることを意味し、あなたがそれを検出するための任意の方法せずに中止することができること、(具体的に保護されていないバックグラウンド処理の欠点を受け入れた場合あなたのログには、あなたがHostingEnvironment.QueueBackgroundWorkItemようなものを使用することができ、)一部のメッセージが欠落することができる。

[WebMethod] 
public MyClass getData() 
{ 
    HostingEnvironment.QueueBackgroundWorkItem(() => Logwriter.writeToLog("Someone requested the WebMethod 'GetData'")); 
    //Do some work 
    return _myClassObject; 
} 

私は私のブログ上alternative approachesの説明を持っています。

+0

こんにちはスティーブン、あなたのサポートのためのタンク。 @Crowcoderであなたの記事を読んで、正しい方向に私を押し込んだ。残念ながら、ASP WebAPIまたはWCFに切り替えることはできません。既存のWebサービスであるからです。私たちのチームは、私がHostingEnvironmentで行ったいくつかのログデータを失っても問題ありません。 – Martin

0

、あなたの方法はすぐに呼び出し元に戻り、ときgetData終了await文の後に再開されます。
task.Resultへの呼び出しは、Taskが完了するまで実行をブロックします。

2

あなたは非常に混ざっています。うまくいけばStephen Clearyも答えますが、ASP.Netでは決してTask.Run()にするべきではありません。 writeToLogを非同期にします。 タスクを返す限り、@ Reneには良いアドバイスがありますが、デッドロックの可能性があるためASP.Netには.Resultを使用しないでください。 ログのような発火と忘却の操作は、驚くほど複雑でdo right.になります。 処理のためにログをキューに送る方がよいでしょう。

関連する問題