Customer Engagement & Dynamics CRM Forum

Expand all | Collapse all

Canceling Waiting Workflows Collectively Using C# Code

  • 1.  Canceling Waiting Workflows Collectively Using C# Code

    SILVER CONTRIBUTOR
    Posted 18 days ago
    Hello All,

    I wanted to reach out to see if anyone has ever had the unfortunate task of going through old workflows that were created well before you took over the project, and are currently waiting in the background doing absolutely nothing. Unfortunately, this is my position as of now which is to clean up massive amounts of workflows however, I must manually go through and cancel waiting workflows 250 at a time. As I understand it, and after having speaking with Microsoft, there is no OOB solution for doing this en masse. From what I understand, I have 3 options;

    1.) Manually cancel each waiting workflow through System Jobs panel, 250 at a time, and then run Bulk Delete on canceled/failed/successful completed workflows. (this will take an eternity, as in total there are probably about 200,000+ waiting workflows. Yes I know, I was shocked as well)

    2.) Write a C# code to push a command to change the Status Reason from waiting for retry due to error/waiting for resources/waiting for timer to canceled. (unfortunately, programming code is not my forte)

    3.) Duplicate the workflow, update it to not produce the waiting portion, and delete the original workflow to basically destroy any currently waiting workflows. (I would rather not do this one, as this could go very terribly wrong)

    Has anyone performed this action before in Dynamics 365 Online with C# code? And if so, might they be willing to share said code as there are many, many instances online covering this but mostly for On Premise. However, some of those sites are questionable, and I would rather reach out to the CRMUG community for any feedback.

    Any help would be greatly appreciated.

    Thank you,

    ------------------------------
    Nicholas Arbour
    TEKLYNX
    Whitefish Bay WI
    ------------------------------


  • 2.  RE: Canceling Waiting Workflows Collectively Using C# Code

    GOLD CONTRIBUTOR
    Posted 18 days ago
    Hello,
    Here is article I wrote back in 2012 - https://butenko.pro/2012/12/20/ms-crm-2011-how-to-cancelpostpone-workfow-instance-using-c/

    If you don't want to write C# what you can do is to use KingswaySoft - just retrieve records of asyncoperation types and update statecode/statuscode to 3/32.

    ------------------------------
    Andrew Butenko
    ------------------------------



  • 3.  RE: Canceling Waiting Workflows Collectively Using C# Code

    SILVER CONTRIBUTOR
    Posted 18 days ago
    Hello Andrew,

    Thanks for the quick response. I'm not sure what KingswaySoft is, but it sounds vaguely familiar. Does this have anything to do with XRMToolBox? If so, I do have that installed and can connect to my organization's instance. I will check out the link, I appreciate the help.

    Thank you,

    ------------------------------
    Nicholas Arbour
    TEKLYNX
    Whitefish Bay WI
    ------------------------------



  • 4.  RE: Canceling Waiting Workflows Collectively Using C# Code

    SILVER CONTRIBUTOR
    Posted 18 days ago
    Hello Andrew,

    I thank you for the link and the information, however, I'm not entirely sure how to go about actually using the code. I followed the additional links to the docs.microsoft site regarding the AsyncOperation (system job) entity messages and methods, as well as the IOrganizationService.Update docs.microsoft page, but they don't really give you any step-by-step instructions how to perform this function. Would you happen to have any advice on how to go about implementing this code to update the Status Reason for the System Jobs?

    Thank you again for the help,

    ------------------------------
    Nicholas Arbour
    TEKLYNX
    Whitefish Bay WI
    ------------------------------



  • 5.  RE: Canceling Waiting Workflows Collectively Using C# Code

    GOLD CONTRIBUTOR
    Posted 18 days ago
    Here is url of KingswaySoft - http://www.kingswaysoft.com/products this is ISV that built adapters for many systems (including Dynamics 365 for CE). It's possible to use it to do your task. Check several videos available here https://www.youtube.com/user/KingswaySoft to get understanding of what it is and how it works.

    Regarding C# code. Snippet I provided in my article can be used after connection to system is obtained and records are retrieved. Here are articles that can help you:
    Obtaining of connection - https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/xrm-tooling/use-connection-strings-xrm-tooling-connect
    Getting records from system - https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/org-service/sample-retrieve-multiple-queryexpression-class

    Good luck.

    ------------------------------
    Andrew Butenko
    ------------------------------



  • 6.  RE: Canceling Waiting Workflows Collectively Using C# Code

    SILVER CONTRIBUTOR
    Posted 18 days ago
    Hello Andrew,

    Thanks for the update. I will look into this further, and I appreciate the additional links to the connections strings and how to retrieve the records. I'll have to study over this before attempting, as I am still fairly new to Dynamics 365.

    Thanks again,

    ------------------------------
    Nicholas Arbour
    TEKLYNX
    Whitefish Bay WI
    ------------------------------



  • 7.  RE: Canceling Waiting Workflows Collectively Using C# Code

    GOLD CONTRIBUTOR
    Posted 17 days ago
    Hi Nicholas,


    This is a fairly simple console app.... Here's a template that is probably 90% of the way ready.  You'll need to update with the correct entity schema name for system jobs, status / status reason attribute, etc.  But it should be a good starting template.  Obviously not tested, I just copied and pasted key parts from several I've written to get the general structure you'd need.


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Configuration;
    using System.ServiceModel.Description;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Client;
    using Microsoft.Xrm.Tooling.Connector;
    using Microsoft.Xrm.Sdk.Query;

    namespace GetUserByGUID
    {
    class GetUserbyGUID
    {
    static void Main(string[] args)
    {

    //EXample Console App Template to connect to CRM, Retrieve Records, and executemultiple on results.
    string CRMConnectionString = @"AuthType = Office365; URL = https://companyname.crm.dynamics.com; Username=username@companyname.com; Password=userpassword";

    //Get CRM Connection
    Console.WriteLine("Connecting to CRM... ");
    CrmServiceClient crmConnection = new CrmServiceClient(CRMConnectionString);
    IOrganizationService crmService = crmConnection.OrganizationServiceProxy;

    Console.WriteLine("Executing Query... ");
    //example query.
    string FetchXMLQuery = @"<fetch version='1.0' output-format='xml - platform' mapping='logical' distinct='false'>< entity name = 'new_changeorder' >< attribute name = 'new_subject' />< attribute name = 'createdon' />< attribute name = 'new_changeorderid' />< attribute name = 'new_dateonlytzitest2' />< attribute name = 'new_dateonlytest1' />< attribute name = 'new_originalcontractdate' />< order attribute = 'new_subject' descending = 'false' /></ entity ></ fetch >";

    var attribute1value = "value to find";

    QueryByAttribute query = new QueryByAttribute("new_entityschemaname");
    query.ColumnSet = new ColumnSet("new_attribute1", "new_attribute2", "new_attribute3");
    query.Attributes.AddRange(new string[] { "new_attribute1" });
    query.Values.AddRange(attribute1value);

    //Query the database for Equipment Records.
    EntityCollection RecordsFoundCollection = crmService.RetrieveMultiple(query);

    //Define a set of requests to update records.
    var exMultRequest = new ExecuteMultipleRequest()
    {
    // Assign settings that define execution behavior: continue on error, return responses.
    Settings = new ExecuteMultipleSettings()
    {
    ContinueOnError = true,
    ReturnResponses = true
    },
    // Create an empty organization request collection.
    Requests = new OrganizationRequestCollection()
    };

    //create individual update requests.
    foreach (Entity e in RecordsFoundCollection)
    {
    UpdateRequest createRequest = new UpdateRequest { Target = e };
    // add the field to be updated
    e.Attributes["new_attributname"] = "desiredvalue";
    exMultRequest.Requests.Add(createRequest);
    }

    //Submit the requests.
    ExecuteMultipleResponseItem responses = (ExeuteMultipleResponse)crmService.Execute(exMultRequest);
    }

    }
    }

    ------------------------------
    Ryan Perry
    Business Systems Analyst
    Auric Solar
    ------------------------------



  • 8.  RE: Canceling Waiting Workflows Collectively Using C# Code

    TOP CONTRIBUTOR
    Posted 17 days ago
    Hi Nicholas
    I have just a little question: Do you want to get rid of all the waiting workflows? Are they all the same so that you can identify them in Advanced Find? I had a similar issue and I created a custom view and than just used bulk delete function on system jobs.

    ------------------------------
    Axel Girgensohn
    Dynamics CRM Specialist
    Aller Media AB
    ------------------------------



If you've found this thread useful, dive deeper into User Group community content by role