{
  "schema_version": 2,
  "id": "develop/clients/dotnet/condexec",
  "title": "Conditional execution",
  "url": "https://redis.io/docs/latest/develop/clients/dotnet/condexec/",
  "summary": "Understand how `StackExchange.Redis` uses conditional execution.",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-09-08T15:21:05+01:00",
  "page_type": "content",
  "content_hash": "cfa7911d7995689e565338d7bb0ac8f8d4a89f0d544869de8b24cd035e2dc666",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "Most Redis client libraries use transactions with the\n[`WATCH`](https://redis.io/docs/latest/commands/watch) command as the main way to prevent\ntwo clients writing to the same key at once (see [Transactions](https://redis.io/docs/latest/develop/using-commands/transactions) for more information). Unfortunately, this approach is\ndifficult to use explicitly in `StackExchange.Redis`. Its\n[multiplexing](https://redis.io/docs/latest/develop/clients/pools-and-muxing) system\nis highly efficient and convenient but can also cause bad interactions\nwhen different connections use watched transactions at the same time.\n\nInstead, `StackExchange.Redis` relies more heavily on conditional execution. This comes\nin two basic forms, `When` conditions and transaction conditions, both of which\nare explained in the sections below."
    },
    {
      "id": "when-conditions",
      "title": "`When` conditions",
      "role": "content",
      "text": "Several commands have variants that only execute if the key they change\nalready exists (or alternatively, if it doesn't already exist). For\nexample, the [`SET`](https://redis.io/docs/latest/commands/set) command has the\nvariants [`SETEX`](https://redis.io/docs/latest/commands/setex) (set when the key exists),\nand [`SETNX`](https://redis.io/docs/latest/commands/setnx) (set when the key doesn't exist).\n\nInstead of providing the different variants of these commands, `StackExchange.Redis`\nlets you add a `When` condition to the basic command to access its variants.\nThe following example demonstrates this for the\n[`HashSet()`](https://redis.io/docs/latest/commands/hset) command.\n\n\n\n[code example]\n\nThe available conditions are `When.Exists`, `When.NotExists`, and the default\n`When.Always`."
    },
    {
      "id": "transaction-conditions",
      "title": "Transaction conditions",
      "role": "content",
      "text": "`StackExchange.Redis` also supports a more extensive set of conditions that you\ncan add to transactions. They are implemented internally using\n[`WATCH`](https://redis.io/docs/latest/commands/watch) commands in a way that is\nguaranteed to be safe, without interactions between different clients.\nAlthough conditions don't provide exactly the same behavior as\nexplicit `WATCH` commands, they are convenient to use and execute\nefficiently.\n\nThe example below shows how to use the `AddCondition()` method on\na transaction to let it run only if a specified hash key does not\nalready exist. See\n[Pipelines and transactions](https://redis.io/docs/latest/develop/clients/dotnet/transpipe)\nfor more information about transactions.\n\n\n\n[code example]\n\nThe table below describes the full set of conditions you can add to\na transaction. Note that you can add more than one condition to the\nsame transaction if necessary.\n\n| Condition | Description |\n| :-- | :-- |\n| `HashEqual` | Enforces that the given hash-field must have the specified value. |\n| `HashExists` | Enforces that the given hash-field must exist. |\n| `HashNotEqual` | Enforces that the given hash-field must not have the specified value. |\n| `HashNotExists` | Enforces that the given hash-field must not exist. |\n| `KeyExists` | Enforces that the given key must exist. |\n| `KeyNotExists` | Enforces that the given key must not exist. |\n| `ListIndexEqual` | Enforces that the given list index must have the specified value. |\n| `ListIndexExists` | Enforces that the given list index must exist. |\n| `ListIndexNotEqual` | Enforces that the given list index must not have the specified value. |\n| `ListIndexNotExists` | Enforces that the given list index must not exist. |\n| `StringEqual` | Enforces that the given key must have the specified value. |\n| `StringNotEqual` | Enforces that the given key must not have the specified value. |\n| `HashLengthEqual` | Enforces that the given hash length is a certain value. |\n| `HashLengthLessThan` | Enforces that the given hash length is less than a certain value. |\n| `HashLengthGreaterThan` | Enforces that the given hash length is greater than a certain value. |\n| `StringLengthEqual` | Enforces that the given string length is a certain value. |\n| `StringLengthLessThan` | Enforces that the given string length is less than a certain value. |\n| `StringLengthGreaterThan` | Enforces that the given string length is greater than a certain value. |\n| `ListLengthEqual` | Enforces that the given list length is a certain value. |\n| `ListLengthLessThan` | Enforces that the given list length is less than a certain value. |\n| `ListLengthGreaterThan` | Enforces that the given list length is greater than a certain value. |\n| `SetLengthEqual` | Enforces that the given set cardinality is a certain value. |\n| `SetLengthLessThan` | Enforces that the given set cardinality is less than a certain value. |\n| `SetLengthGreaterThan` | Enforces that the given set cardinality is greater than a certain value. |\n| `SetContains` | Enforces that the given set contains a certain member. |\n| `SetNotContains` | Enforces that the given set does not contain a certain member. |\n| `SortedSetLengthEqual` | Enforces that the given sorted set cardinality is a certain value. |\n| `SortedSetLengthEqual` | Enforces that the given sorted set contains a certain number of members with scores in the given range. |\n| `SortedSetLengthLessThan` | Enforces that the given sorted set cardinality is less than a certain value. |\n| `SortedSetLengthLessThan` | Enforces that the given sorted set contains less than a certain number of members with scores in the given range. |\n| `SortedSetLengthGreaterThan` | Enforces that the given sorted set cardinality is greater than a certain value. |\n| `SortedSetLengthGreaterThan` | Enforces that the given sorted set contains more than a certain number of members with scores in the given range. |\n| `SortedSetContains` | Enforces that the given sorted set contains a certain member. |\n| `SortedSetNotContains` | Enforces that the given sorted set does not contain a certain member. |\n| `SortedSetEqual` | Enforces that the given sorted set member must have the specified score. |\n| `SortedSetNotEqual` | Enforces that the given sorted set member must not have the specified score. |\n| `SortedSetScoreExists` | Enforces that the given sorted set must have the given score. |\n| `SortedSetScoreNotExists` | Enforces that the given sorted set must not have the given score. |\n| `SortedSetScoreExists` | Enforces that the given sorted set must have the specified count of the given score. |\n| `SortedSetScoreNotExists` | Enforces that the given sorted set must not have the specified count of the given score. |\n| `StreamLengthEqual` | Enforces that the given stream length is a certain value. |\n| `StreamLengthLessThan` | Enforces that the given stream length is less than a certain value. |\n| `StreamLengthGreaterThan` | Enforces that the given stream length is greater than a certain value. |"
    }
  ],
  "examples": [
    {
      "id": "when-conditions-ex0",
      "language": "csharp",
      "code": "bool resp7 = db.HashSet(\"Details\", \"SerialNumber\", \"12345\");\nConsole.WriteLine(resp7); // >>> true\n\ndb.HashSet(\"Details\", \"SerialNumber\", \"12345A\", When.NotExists);\nstring resp8 = db.HashGet(\"Details\", \"SerialNumber\");\nConsole.WriteLine(resp8); // >>> 12345\n\ndb.HashSet(\"Details\", \"SerialNumber\", \"12345A\");\nstring resp9 = db.HashGet(\"Details\", \"SerialNumber\");\nConsole.WriteLine(resp9); // >>> 12345A",
      "section_id": "when-conditions"
    },
    {
      "id": "transaction-conditions-ex0",
      "language": "csharp",
      "code": "var watchedTrans = db.CreateTransaction();\n\nwatchedTrans.AddCondition(Condition.KeyNotExists(\"customer:39182\"));\n\nvar updateTask = watchedTrans.HashSetAsync(\n    \"customer:39182\",\n    new HashEntry[]{\n        new HashEntry(\"name\", \"David\"),\n        new HashEntry(\"age\", \"27\")\n    }\n);\n\nbool succeeded = db.Wait(watchedTrans.ExecuteAsync());\ndb.Wait(updateTask);\nConsole.WriteLine(succeeded); // >>> true",
      "section_id": "transaction-conditions"
    }
  ]
}
