ConcurrencyMode Výčet
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Určuje, zda třída služby podporuje režimy operace s jedním vláknem nebo více vlákny.
public enum class ConcurrencyMode
public enum ConcurrencyMode
type ConcurrencyMode =
Public Enum ConcurrencyMode
- Dědičnost
Pole
| Name | Hodnota | Description |
|---|---|---|
| Single | 0 | Instance služby je jednovláknová a nepřijímá opakované volání. InstanceContextMode Pokud je Singlevlastnost a další zprávy dorazí, zatímco instance služby volání, tyto zprávy musí počkat, až bude služba k dispozici nebo až do vypršení časového limitu zpráv. |
| Reentrant | 1 | Instance služby je jednovláknová a přijímá opakované volání. Služba reentrant přijímá volání při volání jiné služby; je proto vaší zodpovědností ponechat stav objektu konzistentní před popisky a musíte potvrdit, že data místní operace jsou po bublinových popiscích platná. Všimněte si, že instance služby je odemknutá pouze voláním jiné služby přes kanál WCF. V tomto případě může volaná služba znovu zadat první službu prostřednictvím zpětného volání. Pokud první služba není znovu zaváděná, výsledkem posloupnosti volání je zablokování. Podrobnosti najdete v ConcurrencyMode. |
| Multiple | 2 | Instance služby je vícevláknová. Nejsou provedeny žádné záruky synchronizace. Vzhledem k tomu, že ostatní vlákna můžou objekt služby kdykoli změnit, musíte zpracovávat synchronizaci a konzistenci stavu vždy. |
Příklady
Následující příklad kódu ukazuje rozdíl mezi použitím Single, Reentrant a Multiple. Tato ukázka se nezkompiluje bez skutečné implementace, ale předvádí druh threadingu záruky, že WCF dělá a co znamená pro váš provozní kód.
using System;
using System.ServiceModel;
[ServiceContract]
public interface IHttpFetcher
{
[OperationContract]
string GetWebPage(string address);
}
// These classes have the invariant that:
// this.slow.GetWebPage(this.cachedAddress) == this.cachedWebPage.
// When you read cached values you can assume they are valid. When
// you write the cached values, you must guarantee that they are valid.
// With ConcurrencyMode.Single, WCF does not call again into the object
// so long as the method is running. After the operation returns the object
// can be called again, so you must make sure state is consistent before
// returning.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
class SingleCachingHttpFetcher : IHttpFetcher
{
string cachedWebPage;
string cachedAddress;
readonly IHttpFetcher slow;
public string GetWebPage(string address)
{
// <-- Can assume cache is valid.
if (this.cachedAddress == address)
{
return this.cachedWebPage;
}
// <-- Cache is no longer valid because we are changing
// one of the values.
this.cachedAddress = address;
string webPage = slow.GetWebPage(address);
this.cachedWebPage = webPage;
// <-- Cache is valid again here.
return this.cachedWebPage;
// <-- Must guarantee that the cache is valid because we are returning.
}
}
// With ConcurrencyMode.Reentrant, WCF makes sure that only one
// thread runs in your code at a time. However, when you call out on a
// channel, the operation can get called again on another thread. Therefore
// you must confirm that state is consistent both before channel calls and
// before you return.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
class ReentrantCachingHttpFetcher : IHttpFetcher
{
string cachedWebPage;
string cachedAddress;
readonly SlowHttpFetcher slow;
public ReentrantCachingHttpFetcher()
{
this.slow = new SlowHttpFetcher();
}
public string GetWebPage(string address)
{
// <-- Can assume that cache is valid.
if (this.cachedAddress == address)
{
return this.cachedWebPage;
}
// <-- Must guarantee that the cache is valid, because
// the operation can be called again before we return.
string webPage = slow.GetWebPage(address);
// <-- Can assume cache is valid.
// <-- Cache is no longer valid because we are changing
// one of the values.
this.cachedAddress = address;
this.cachedWebPage = webPage;
// <-- Cache is valid again here.
return this.cachedWebPage;
// <-- Must guarantee that cache is valid because we are returning.
}
}
// With ConcurrencyMode.Multiple, threads can call an operation at any time.
// It is your responsibility to guard your state with locks. If
// you always guarantee you leave state consistent when you leave
// the lock, you can assume it is valid when you enter the lock.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
class MultipleCachingHttpFetcher : IHttpFetcher
{
string cachedWebPage;
string cachedAddress;
readonly SlowHttpFetcher slow;
readonly object ThisLock = new object();
public MultipleCachingHttpFetcher()
{
this.slow = new SlowHttpFetcher();
}
public string GetWebPage(string address)
{
lock (this.ThisLock)
{
// <-- Can assume cache is valid.
if (this.cachedAddress == address)
{
return this.cachedWebPage;
// <-- Must guarantee that cache is valid because
// the operation returns and releases the lock.
}
// <-- Must guarantee that cache is valid here because
// the operation releases the lock.
}
string webPage = slow.GetWebPage(address);
lock (this.ThisLock)
{
// <-- Can assume cache is valid.
// <-- Cache is no longer valid because the operation
// changes one of the values.
this.cachedAddress = address;
this.cachedWebPage = webPage;
// <-- Cache is valid again here.
// <-- Must guarantee that cache is valid because
// the operation releases the lock.
}
return webPage;
}
}
Poznámky
ConcurrencyMode se používá ve spojení s ConcurrencyMode vlastností určit, zda třída služby podporuje režimy operace s jedním vláknem nebo vícevláknovým režimem. Operace s jedním vláknem může být buď znovu zaententovaná, nebo nesdělovaná.
Následující tabulka ukazuje, kdy technologie Windows Communication Foundation (WCF) umožňuje vyvolání operace, zatímco probíhá jiná operace v závislosti na závislosti na ConcurrencyMode.
| Hodnota ConcurrencyMode | Je možné vyvolat novou operaci? |
|---|---|
| Single | Nikdy. |
| Znovu zadat | Pouze při vyvolání jiné služby nebo zpětného volání. |
| Multiple | Vždy. |