欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
WCF之旅(6):在Winform Application中調用Duplex Service出現TimeoutException的原因和解決方案
前一篇關(guān)于如何通過(guò)WCF進(jìn)行 雙向通信的文章在文章中提供了一個(gè)如果在Console Application 調用Duplex WCF Service的Sample。前幾天有留言說(shuō),在沒(méi)有做任何改動(dòng)得情況下,把 作為Client的Console Application 換成Winform Application,運行程序的時(shí)候總是出現Timeout的錯誤。我覺(jué)得這是一個(gè)很好的問(wèn)題,通過(guò)這個(gè)問(wèn)題,我們可以更加深入地理解WCF的消息交換的機制。

1.問(wèn)題重現

首先我們來(lái)重現這個(gè)錯誤,在這里我只寫(xiě)WinForm的代碼,其他的內容請參考我的文章。Client端的Proxy Class(DuplexCalculatorClient)的定義沒(méi)有任何變化。我們先來(lái)定義用于執行回調操作(Callback)的類(lèi)——CalculatorCallbackHandler.cs。代碼很簡(jiǎn)單,就是通過(guò)Message Box的方式顯示運算的結果。

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using Artech.DuplexWCFService.Contract;
using System.ServiceModel;

namespace Artech. WCFService.Client
{
    [ServiceBehavior(ConcurrencyMode 
= ConcurrencyMode.Multiple)]
    
public class CalculatorCallbackHandler : ICalculatorCallback
    
{
        
ICalculatorCallback Members
    }

}

接著(zhù)我們來(lái)設計我們的UI,很簡(jiǎn)單,無(wú)需多說(shuō)。


代碼如下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace Artech. WCFService.Client
{
    
public partial class Form1 : Form
    
{
        
private DuplexCalculatorClient _calculator;
        
private double _op1;
        
private double _op2;
        
public Form1()
        
{
            InitializeComponent();
        }

        
private void Form1_Load(object sender, EventArgs e)
        
{
            
this._calculator = new DuplexCalculatorClient(new System.ServiceModel.InstanceContext(new CalculatorCallbackHandler()));
        }

        
private void Calculate()
        
{
            
this._calculator.Add(this._op1, this._op2);
        }

        
private void buttonCalculate_Click(object sender, EventArgs e)
        
{
            
if (!double.TryParse(this.textBoxOp1.Text.Trim(), out this._op1))
            
{
                MessageBox.Show(
"Please enter a valid number","Error", MessageBoxButtons.OK,  MessageBoxIcon.Error);
                
this.textBoxOp1.Focus();
            }

            
if (!double.TryParse(this.textBoxOp2.Text.Trim(), out this._op2))
            
{
                MessageBox.Show(
"Please enter a valid number","Error", MessageBoxButtons.OK,  MessageBoxIcon.Error);
                
this.textBoxOp1.Focus();
            }

            
try
            
{
                
this.Calculate();
            }

            
catch (Exception ex)
            
{
                MessageBox.Show(ex.Message, 
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
 
        }

    }

}

啟動(dòng)Host,然后隨啟動(dòng)Client,在兩個(gè)Textbox中輸入數字2和3,Click Calculate按鈕,隨后整個(gè)UI被鎖住,無(wú)法響應用戶(hù)操作。一分后,出現下面的錯誤。


我們從上面的Screen Shot中可以看到這樣一個(gè)很有意思的現象,運算結果被成功的顯示,顯示,但是有個(gè)Exception被拋出:”This request operation sent to http://localhost:6666/myClient/4f4ebfeb-5c84-45dc-92eb-689d631b337f did not receive a reply within the configured timeout (00:00:57.7300000). The time allotted to this operation may have been a portion of a longer timeout. This may be because the service is still processing the operation or because the service was unable to send a reply message. Please consider increasing the operation timeout (by casting the channel/proxy to IContextChannel and setting the OperationTimeout property) and ensure that the service is able to connect to the client.”。

2.原因分析

在我開(kāi)始分析為什么會(huì )造成上面的情況之前,我要申明一點(diǎn):由于找不到任何相關(guān)的資料,以下的結論是我從試驗推導出來(lái),我不能保證我的分析是合理的,因為有些細節我自己都還不能自圓其說(shuō),我將在后面提到。我希望有誰(shuí)對此了解的人能夠指出我的問(wèn)題, 我將不勝感激。

我們先來(lái)看看整個(gè)調用過(guò)程的Message Exchange過(guò)程,通過(guò)前面相關(guān)的介紹,我們知道WCF可以采用三種不同的Message Exchange Pattern(MEP)——One-way,Request/Response,Duplex。其實(shí)從本質(zhì)上講,One-way,Request/Response是兩種基本的MEP, Duplex可以看成是這兩種MEP的組合——兩個(gè)One-way,兩個(gè)Request/Response或者是一個(gè)One-way和一個(gè)Request/Response。在定義Service Contract的時(shí)候,如果我們沒(méi)有為某個(gè)Operation顯式指定為One-way (IsOneWay = true), 那么默認采用Request/Response方式。我們現在的Sample就是由兩個(gè)Request/Response MEP組成的Duplex MEP。


從上圖中我們可以很清楚地看出真個(gè)Message Exchange過(guò)程,Client調用Duplex Calculator Service,Message先從Client傳遞到Service,Service執行Add操作,得到運算結果之后,從當前的OperationContext獲得Callback對象,發(fā)送一個(gè)Callback 請求道Client(通過(guò)在Client注冊的Callback Channel:http://localhost:6666/myClient)。但是,由于Client端調用Calculator Service是在主線(xiàn)程中,我們知道一個(gè)UI的程序的主線(xiàn)程一直處于等待的狀態(tài),它是不會(huì )有機會(huì )接收來(lái)自Service端的Callback請求的。但是由于Callback Operation是采用Request/Response方式調用的,所以它必須要收到來(lái)自Client端Reply來(lái)確定操作正常結束。這實(shí)際上形成了一個(gè)Deadlock,可以想象它用過(guò)也不能獲得這個(gè)Reply,所以在一個(gè)設定的時(shí)間內(默認為1分鐘),它會(huì )拋出Timeout 的Exception, Error Message就像下面這個(gè)樣子。

”This request operation sent to http://localhost:6666/myClient/4f4ebfeb-5c84-45dc-92eb-689d631b337f did not receive a reply within the configured timeout (00:00:57.7300000). The time allotted to this operation may have been a portion of a longer timeout. This may be because the service is still processing the operation or because the service was unable to send a reply message. Please consider increasing the operation timeout (by casting the channel/proxy to IContextChannel and setting the OperationTimeout property) and ensure that the service is able to connect to the client.”。

3.解決方案

方案1:多線(xiàn)程異步調用

既然WinForm的主線(xiàn)程不能接受Service的Callback,那么我們就在另一個(gè)線(xiàn)程調用Calculator Service,在這個(gè)新的線(xiàn)程接受來(lái)自Service的Callback。

于是我們改變Client的代碼:

private void buttonCalculate_Click(object sender, EventArgs e)
        
{
            
if (!double.TryParse(this.textBoxOp1.Text.Trim(), out this._op1))
            
{
                MessageBox.Show(
"Please enter a valid number","Error", MessageBoxButtons.OK,  MessageBoxIcon.Error);
                
this.textBoxOp1.Focus();
            }


            
if (!double.TryParse(this.textBoxOp2.Text.Trim(), out this._op2))
            
{
                MessageBox.Show(
"Please enter a valid number","Error", MessageBoxButtons.OK,  MessageBoxIcon.Error);
                
this.textBoxOp1.Focus();
            }

            
try
            
{
                Thread newThread 
= new Thread(new ThreadStart(this.Calculate));
                newThread.Start();        
            }

            
catch (Exception ex)
            
{
                MessageBox.Show(ex.Message, 
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
             
        }

通過(guò)實(shí)驗證明,這種方式是可行的。

方案2:采用One-way的方式調用Service 和Callback,既然是因為Exception發(fā)生在不同在規定的時(shí)間內不能正常地收到對應的Reply,那種我就 允許你不必收到Reply就好了——實(shí)際上在本例中,對于A(yíng)dd方法,我們根本就不需要有返回結果,我們完全可以使用One-way的方式調用Operation。在這種情況下,我們只需要改變DuplexCalculator和CalculatorCallback的Service Contract定義就可以了。

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

namespace Artech.DuplexWCFService.Contract
{
    [ServiceContract(CallbackContract 
= typeof(ICalculatorCallback))]
    
public interface IDuplexCalculator
    
{
        [OperationContract(IsOneWay 
=true)]
        
void Add(double x, double y);
    }

}

從Message Exchange的角度講,這種方式實(shí)際上是采用下面一種消息交換模式(MEP):


進(jìn)一步地,由于Callback也沒(méi)有返回值,我們也可以把Callback操作也標記為One-way.

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

namespace Artech.DuplexWCFService.Contract
{
    
//[ServiceContract]
    public interface ICalculatorCallback
    
{
        [OperationContract(IsOneWay 
= true)]
        
void  ShowResult(double x, double y, double result);
    }

}

那么現在的Message Exchange成為下面一種方式:


實(shí)現證明這兩種方式也是可行的。

4 .疑問(wèn)

雖然直到現在,所有的現象都說(shuō)得過(guò)去,但是仍然有一個(gè)問(wèn)題不能得到解釋?zhuān)喝绻且驗閃inform的主線(xiàn)程不能正常地接受來(lái)自Service的Callback才導致了Timeout Exception,那為什么Callback操作能過(guò)正常執行呢?而且通過(guò)我的實(shí)驗證明他基本上是在拋出Exception的同時(shí)執行的。(參考第2個(gè)截圖)

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
回調的線(xiàn)程關(guān)聯(lián)性
Integrating Windows Workflow Foundation and Windows Communication Foundation (轉于 MSDN)
Windows Vista aware NT Service interacting with the desktop
Application Architecture for Applications Built on BEA WebLogic Platform? 8.1
通過(guò)實(shí)例分析WCF Duplex消息交換
WCF的雙向通訊-基于Http的雙向通訊 V.S. 基于TCP的雙向通訊 - Artech - 博客園
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久