Aracılığıyla paylaş


Bağıntı Sorunlarını Giderme

bağıntı, iş akışı hizmeti iletilerini birbiriyle ve doğru iş akışı örneğiyle ilişkilendirmek için kullanılır, ancak doğru yapılandırılmazsa iletiler alınmaz ve uygulamalar düzgün çalışmaz. Bu konu, bağıntı sorunlarını gidermeye yönelik çeşitli yöntemlere genel bir bakış sağlar ve ayrıca bağıntı kullandığınızda oluşabilecek bazı yaygın sorunları listeler.

UnknownMessageReceived Olayını İşleme

Olay UnknownMessageReceived , var olan bir örnekle ilişkilendirilemeyen iletiler de dahil olmak üzere bir hizmet tarafından bilinmeyen bir ileti alındığında gerçekleşir. Şirket içinde barındırılan hizmetler için bu olay konak uygulamasında işlenebilir.

host.UnknownMessageReceived += delegate(object sender, UnknownMessageReceivedEventArgs e)
{
    Console.WriteLine("Unknown Message Received:");
    Console.WriteLine(e.Message);
};

Web'de barındırılan hizmetler için, bu olay öğesinden WorkflowServiceHostFactory bir sınıf türetilerek ve geçersiz kılınarak CreateWorkflowServiceHostişlenebilir.

class CustomFactory : WorkflowServiceHostFactory
{
    protected override WorkflowServiceHost CreateWorkflowServiceHost(Activity activity, Uri[] baseAddresses)
    {
        // Create the WorkflowServiceHost.
        WorkflowServiceHost host = new WorkflowServiceHost(activity, baseAddresses);

        // Handle the UnknownMessageReceived event.
        host.UnknownMessageReceived += delegate(object sender, UnknownMessageReceivedEventArgs e)
        {
            Console.WriteLine("Unknown Message Received:");
            Console.WriteLine(e.Message);
        };

        return host;
    }
}

Bu özel WorkflowServiceHostFactory daha sonra hizmetin dosyasında belirtilebilir svc .

<% @ServiceHost Language="C#" Service="OrderServiceWorkflow" Factory="CustomFactory" %>

Bu işleyici çağrıldığında, iletisi özelliğini UnknownMessageReceivedEventArgskullanarak Message alınabilir ve aşağıdaki iletiye benzer.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://localhost:8080/OrderService</To>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService/AddItem</Action>
  </s:Header>
  <s:Body>
    <AddItem xmlns="http://tempuri.org/">
      <Item>Books</Item>
    </AddItem>
  </s:Body>
</s:Envelope>

İşleyiciye gönderilen iletilerin incelenmesi, iletinin UnknownMessageReceived iş akışı hizmetinin bir örneğiyle neden bağıntılı olmadığı hakkında ipuçları sağlayabilir.

İş Akışının İlerleme Durumunu İzlemek için İzlemeyi Kullanma

İzleme, bir iş akışının ilerleme durumunu izlemenin bir yolunu sağlar. Varsayılan olarak, izleme kayıtları iş akışı yaşam döngüsü olayları, etkinlik yaşam döngüsü olayları, hata yayma ve yer işareti yeniden başlatma için yayılır. Ayrıca, özel izleme kayıtları özel etkinlikler tarafından yayılabilir. Bağıntı sorunlarını giderirken etkinlik izleme kayıtları, yer işareti yeniden sağlama kayıtları ve hata yayma kayıtları en yararlı olanlardır. Etkinlik izleme kayıtları, iş akışının geçerli ilerleme durumunu belirlemek için kullanılabilir ve şu anda hangi mesajlaşma etkinliğinin iletileri beklediğini belirlemeye yardımcı olabilir. Yer işareti yeniden başlatma kayıtları, iş akışı tarafından bir ileti alındığını ve hata yayma kayıtlarının iş akışındaki hataların kaydını sağladığından yararlıdır. İzlemeyi etkinleştirmek için içinde isteneni TrackingParticipantWorkflowExtensionsWorkflowServiceHostbelirtin. Aşağıdaki örnekte, ConsoleTrackingParticipant ( Özel İzleme örneğinden) varsayılan izleme profili kullanılarak yapılandırılır.

host.WorkflowExtensions.Add(new ConsoleTrackingParticipant());

ConsoleTrackingParticipant gibi bir izleme katılımcısı, konsol penceresi olan şirket içinde barındırılan iş akışı hizmetleri için kullanışlıdır. Web'de barındırılan bir hizmet için, izleme bilgilerini dayanıklı bir depoya kaydeden bir izleme katılımcısı, örneğin yerleşik EtwTrackingParticipantveya bilgileri bir dosyaya kaydeden özel izleme katılımcısı kullanılmalıdır.

Web'de barındırılan bir iş akışı hizmeti için izlemeyi izleme ve yapılandırma hakkında daha fazla bilgi için bkz . İş Akışı İzleme ve İzleme, İş Akışı için İzlemeyi Yapılandırma ve İzleme [WF Örnekleri] örnekleri.

WCF İzlemeyi Kullanma

WCF izleme, bir iş akışı hizmetinden gelen ve giden ileti akışının izlemesini sağlar. Bu izleme bilgileri, özellikle içerik tabanlı bağıntı için bağıntı sorunlarını giderirken yararlıdır. İzlemeyi etkinleştirmek için, iş akışı hizmeti Web'de system.diagnostics barındırılıyorsa dosyanın bölümünde web.config istenen izleme dinleyicilerini veya app.config iş akışı hizmeti şirket içinde barındırılıyorsa dosyayı belirtin. İletilerin içeriğini izleme dosyasına eklemek için öğesinin bölümündeki system.serviceModelöğesinde diagnostics öğesini messageLogginglogEntireMessage belirtintrue. Aşağıdaki örnekte, iletilerin içeriği de dahil olmak üzere izleme bilgileri adlı service.svclogbir dosyaya yazılacak şekilde yapılandırılır.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="Information" propagateActivity="true">
        <listeners>
          <add name="corr"/>
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add name="corr"/>
        </listeners>
      </source>
    </sources>

    <sharedListeners>
      <add name="corr" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\logs\service.svclog">
      </add>
    </sharedListeners>
  </system.diagnostics>

  <system.serviceModel>
    <diagnostics>
      <messageLogging logEntireMessage="true" logMalformedMessages="false"
         logMessagesAtServiceLevel="false" logMessagesAtTransportLevel="true" maxSizeOfMessageToLog="2147483647">
      </messageLogging>
    </diagnostics>
  </system.serviceModel>
</configuration>

içinde service.svclogbulunan izleme bilgilerini görüntülemek için Hizmet İzleme Görüntüleyici aracı (SvcTraceViewer.exe) kullanılır. Bu özellikle içerik tabanlı bağıntı sorunlarını giderirken yararlıdır çünkü ileti içeriğini görüntüleyebilir ve tam olarak nelerin geçirildiğini ve içerik tabanlı bağıntı CorrelationQuery için ile eşleşip eşleşmediğini görebilirsiniz. WCF izleme hakkında daha fazla bilgi için bkz. Hizmet İzleme GörüntüleyiciSi Aracı (SvcTraceViewer.exe), İzlemeyi Yapılandırma ve Uygulamanızın Sorunlarını Gidermek için İzlemeyi Kullanma.

Yaygın Bağlam Değişimi Bağıntı Sorunları

Belirli bağıntı türleri, bağıntının düzgün çalışması için belirli bir bağlama türünün kullanılmasını gerektirir. Örnek olarak, gibi BasicHttpBindingiki yönlü bağlama gerektiren istek-yanıt bağıntısı ve gibi BasicHttpContextBindingbağlam tabanlı bir bağlama gerektiren bağlam değişimi bağıntısı verilebilir. Bağlamaların çoğu iki yönlü işlemleri desteklediğinden, bu istek-yanıt bağıntısı için yaygın bir sorun değildir, ancak , WSHttpContextBindingve NetTcpContextBindinggibi BasicHttpContextBindingbağlam tabanlı bağlamalardan yalnızca birkaçı vardır. Bu bağlamalardan biri kullanılmazsa, bir iş akışı hizmetine yapılan ilk çağrı başarılı olur, ancak sonraki çağrılar aşağıdakiyle FaultExceptionbaşarısız olur.

There is no context attached to the incoming message for the service
and the current operation is not marked with "CanCreateInstance = true".
In order to communicate with this service check whether the incoming binding
supports the context protocol and has a valid context initialized.

Bağlam bağıntısı için kullanılan bağlam bilgileri, iki yönlü bir işlem kullanılırken bağlam bağıntısını başlatan etkinliğe döndürülebilir SendReplyReceive veya işlem tek yönlüyse çağıran tarafından belirtilebilir. Bağlam çağıran tarafından gönderilmezse veya iş akışı hizmeti tarafından döndürülmezse, FaultException sonraki bir işlem çağrıldığında daha önce açıklanan aynı değer döndürülür.

Yaygın Request-Reply Bağıntı Sorunları

İstek-yanıt bağıntısı, bir Receive/SendReply iş akışı hizmetinde iki yönlü bir işlem uygulamak için bir çift ve başka bir Web hizmetinde iki yönlü işlemi çağıran bir Send/ReceiveReply çiftle birlikte kullanılır. WCF hizmetinde iki yönlü bir işlem çağrılırken, hizmet geleneksel bir kesinlik temelli kod tabanlı WCF hizmeti olabileceği gibi bir iş akışı hizmeti de olabilir. İstek-yanıt bağıntısını kullanmak için gibi BasicHttpBindingiki yönlü bir bağlama kullanılmalıdır ve işlemler iki yönlü olmalıdır.

İş akışı hizmetinin paralel olarak iki yönlü işlemleri veya çakışan Receive/SendReply veyaReceiveReplySend/çiftleri varsa, tarafından sağlanan WorkflowServiceHost örtük bağıntı tutamacı yönetimi, özellikle yüksek stres senaryolarında yeterli olmayabilir ve iletiler doğru yönlendirilmeyebilir. Bu sorunun oluşmasını önlemek için, istek-yanıt bağıntısını kullanırken her zaman açıkça bir CorrelationHandle belirtmenizi öneririz. İş akışı tasarımcısında Araç Kutusu'nun Mesajlaşma bölümünden SendAndReceiveReply ve ReceiveAndSendReply şablonları kullanılırken, varsayılan CorrelationHandle olarak açıkça yapılandırılır. Kod kullanarak bir iş akışı oluştururken, CorrelationHandle çiftteki CorrelationInitializers ilk etkinliğin içinde belirtilir. Aşağıdaki örnekte, bir Receive etkinlik içinde RequestReplyCorrelationInitializerbelirtilen açık CorrelationHandle bir şekilde yapılandırılır.

Variable<CorrelationHandle> RRHandle = new Variable<CorrelationHandle>();

Receive StartOrder = new Receive
{
    CanCreateInstance = true,
    ServiceContractName = OrderContractName,
    OperationName = "StartOrder",
    CorrelationInitializers =
    {
        new RequestReplyCorrelationInitializer
        {
            CorrelationHandle = RRHandle
        }
    }
};

SendReply ReplyToStartOrder = new SendReply
{
    Request = StartOrder,
    Content = ... // Contains the return value, if any.
};

// Construct a workflow using StartOrder and ReplyToStartOrder.

Bir çift veyaReceiveReplySend/çift Receive/SendReply arasında kalıcılığa izin verilmez. Her iki etkinlik de tamamlanana kadar devam eden kalıcı olmayan bir bölge oluşturulur. Gecikme etkinliği gibi bir etkinlik kalıcı olmayan bu bölgedeyse ve iş akışının boşta olmasına neden olursa, konak boşta kaldığında iş akışlarını kalıcı hale getirmek üzere yapılandırılmış olsa bile iş akışı kalıcı olmaz. Kalıcı etkinlik gibi bir etkinlik kalıcı olmayan bölgede açıkça kalıcı hale gelirse, önemli bir özel durum oluşturulur, iş akışı durdurulür ve çağırana bir FaultException döndürülür. Önemli özel durum iletisi şudur: "System.InvalidOperationException: Kalıcılık etkinlikleri hiçbir kalıcılık bloğu içinde bulunamaz." Bu özel durum çağırana döndürülmedi, ancak izleme etkinleştirildiyse gözlemlenebilir. Arayana FaultException döndürülen için ileti "WorkflowInstance '5836145b-7da2-49d0-a052-a49162adeab6' tamamlandığından işlem gerçekleştirilemedi" şeklindedir.

İstek-yanıt bağıntısı hakkında daha fazla bilgi için bkz. İstek-Yanıt.

Yaygın İçerik Bağıntı Sorunları

İçerik tabanlı bağıntı, bir iş akışı hizmeti birden çok ileti aldığında ve değiştirilen iletilerdeki bir veri parçası istenen örneği tanımladığında kullanılır. İçerik tabanlı bağıntı, iletileri doğru iş akışı örneğine yönlendirmek için iletideki müşteri numarası veya sipariş kimliği gibi bu verileri kullanır. Bu bölümde, içerik tabanlı bağıntı kullanılırken oluşabilecek çeşitli yaygın sorunlar açıklanmaktadır.

Tanımlama Verilerinin Benzersiz Olduğundan Emin Olun

Örneği tanımlamak için kullanılan veriler bir bağıntı anahtarında karma olarak oluşturulur. Bağıntı için kullanılan verilerin benzersiz olduğunu veya karma anahtarda başka bir çakışma oluşabileceğini ve iletilerin yanlış yönlendirilmesine neden olabileceğini garanti etmek için dikkatli olunmalıdır. Örneğin, yalnızca müşteri adına dayalı bir bağıntı, aynı ada sahip birden çok müşteri olabileceğinden çakışmaya neden olabilir. İki nokta üst üste (:) daha sonra karma olan dizeyi oluşturmak üzere ileti sorgusunun anahtarını ve değerini sınırlandırmak için zaten kullanıldığından, iletiyle bağıntı kurmak için kullanılan verilerin bir parçası olarak kullanılmamalıdır. Kalıcılık kullanılıyorsa, geçerli tanımlayıcı verilerin daha önce kalıcı bir örnek tarafından kullanılmadığından emin olun. Kalıcılığı geçici olarak devre dışı bırakmak bu sorunun tanımlanmasına yardımcı olabilir. WCF izleme, hesaplanan bağıntı anahtarını görüntülemek için kullanılabilir ve bu tür bir sorunun hatalarını ayıklamak için yararlıdır.

Yarış Koşulları

Hizmetin bir iletiyi alması ile bağıntının gerçekten başlatılması arasında zaman içinde küçük bir boşluk vardır ve bu sırada izleme iletileri yoksayılır. bir iş akışı hizmeti, istemciden tek yönlü bir işlem üzerinden geçirilen verileri kullanarak içerik tabanlı bağıntıyı başlatırsa ve çağıran hemen izleme iletileri gönderirse, bu iletiler bu aralıkta yoksayılır. Bu durum, bağıntıyı başlatmak için iki yönlü bir işlem kullanılarak veya kullanılarak TransactedReceiveScopeönlenebilir.

Bağıntı Sorgusu Sorunları

Bağıntı sorguları, bir iletideki hangi verilerin iletiyle bağıntı oluşturmak için kullanılacağını belirtmek için kullanılır. Bu veriler bir XPath sorgusu kullanılarak belirtilir. Bir hizmete gönderilen iletiler her şey doğru gibi görünse bile gönderilmiyorsa, sorun giderme stratejilerinden biri XPath sorgusu yerine ileti verilerinin değeriyle eşleşen bir değişmez değer belirtmektir. Değişmez değer belirtmek için işlevini kullanın string . Aşağıdaki örnekte, bir MessageQuerySet değeri için OrderId değişmez değeri 11445 kullanacak şekilde yapılandırılır ve XPath sorgusu açıklama satırı yapılır.

MessageQuerySet = new MessageQuerySet
{
    {
        "OrderId",
        //new XPathMessageQuery("sm:body()/tempuri:StartOrderResponse/tempuri:OrderId")
        new XPathMessageQuery("string('11445')")
    }
}

Bir XPath sorgusu, bağıntı verilerinin alınmaması için yanlış yapılandırılırsa, şu iletiyle bir hata döndürülür: "Bağıntı sorgusu boş bir sonuç kümesi döndürdü. Lütfen uç nokta için bağıntı sorgularının doğru yapılandırıldığından emin olun." Bu sorunu gidermenin hızlı yollarından biri, XPath sorgusunu önceki bölümde açıklandığı gibi değişmez değerle değiştirmektir. Bu sorun, Bağıntı Başlatıcıları veya BağıntıLarıOn Tanımı Ekle iletişim kutularında XPath sorgu oluşturucusunu kullanıyorsanız ve iş akışı hizmetiniz ileti sözleşmelerini kullanıyorsa oluşabilir. Aşağıdaki örnekte bir ileti sözleşmesi sınıfı tanımlanmıştır.

[MessageContract]
public class AddItemMessage
{
    [MessageHeader]
    public string CartId;

    [MessageBodyMember]
    public string Item;
}

Bu ileti sözleşmesi iş akışındaki bir Receive etkinlik tarafından kullanılır. CartId İletinin üst bilgisindeki, iletiyi doğru örnekle ilişkilendirmek için kullanılır. öğesini alan CartId XPath sorgusu iş akışı tasarımcısındaki bağıntı iletişim kutuları kullanılarak oluşturulduysa, aşağıdaki yanlış XPath sorgusu oluşturulur.

sm:body()/xg0:AddItemMessage/xg0:CartId

Etkinlik veriler için parametreler kullandıysa Receive bu XPath sorgusu doğru olabilir, ancak ileti sözleşmesi kullandığından yanlıştır. Aşağıdaki XPath sorgusu, üst bilgiden almak CartId için doğru XPath sorgusudur.

sm:header()/tempuri:CartId

Bu, iletinin gövdesi incelenerek doğrulanabilir.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService/AddItem</Action>
    <h:CartId xmlns:h="http://tempuri.org/">80c95b41-c98d-4660-a6c1-99412206e54c</h:CartId>
  </s:Header>
  <s:Body>
    <AddItemMessage xmlns="http://tempuri.org/">
      <Item>Books</Item>
    </AddItemMessage>
  </s:Body>
</s:Envelope>

Aşağıdaki örnekte, verileri almak için önceki ileti sözleşmesini kullanan bir işlem için yapılandırılmış bir AddItem etkinlik gösterilmektedirReceive. XPath sorgusu doğru yapılandırıldı.

<Receive CorrelatesWith="[CCHandle] OperationName="AddItem" ServiceContractName="p:IService">
  <Receive.CorrelatesOn>
    <XPathMessageQuery x:Key="key1">
      <XPathMessageQuery.Namespaces>
        <ssx:XPathMessageContextMarkup>
          <x:String x:Key="xg0">http://schemas.datacontract.org/2004/07/MessageContractWFService</x:String>
        </ssx:XPathMessageContextMarkup>
      </XPathMessageQuery.Namespaces>sm:header()/tempuri:CartId</XPathMessageQuery>
  </Receive.CorrelatesOn>
  <ReceiveMessageContent DeclaredMessageType="m:AddItemMessage">
    <p1:OutArgument x:TypeArguments="m:AddItemMessage">[AddItemMessage]</p1:OutArgument>
  </ReceiveMessageContent>
</Receive>